题目来源:
CSUOJ 2298: Animal Companion in Maze
CodeForces Gym101158H Animal Companion in Maze
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#include <sstream>
#define LL long long
#define LD long double
#define ULL unsigned long long
#define UI unsigned int
#define _for(i,j,k) for(int i=j;i<=k;i++)
#define for_(i,j,k) for(int i=j;i>=k;i--)
#define lowbit(x) (x&-x)
#define ls(x) x<<1
#define rs(x) x<<1|1
//#pragma comment(linker, "/STACK:10240000000,10240000000")
using namespace std;
const int maxn = 1e5+5;
struct E{
int mkv,u,v;
};
int n,m;
int head[maxn],e[maxn<<2],net[maxn<<2],cnt;
int head2[maxn],net2[maxn<<2],cnt2;
E e2[maxn<<2];
int dfn[maxn],low[maxn],mkr[maxn],df,mk,inq[maxn];
stack<int> st;
queue<int> q;
int ein[maxn],dp[maxn][2],rt[maxn];
void add_edge(int u,int v){
e[++cnt]=v;
net[cnt]=head[u];
head[u]=cnt;
}
void add_edge2(int u,int v){
e2[++cnt2].mkv=mkr[v];
e2[cnt2].u=u;
e2[cnt2].v=v;
net2[cnt2]=head2[mkr[u]];
head2[mkr[u]]=cnt2;
}
void tarjan(int u){
dfn[u]=low[u]=++df;
st.push(u);
inq[u]=1;
for(int i=head[u];i;i=net[i]){
if(!dfn[e[i]]) tarjan(e[i]);
if(inq[e[i]]) low[u]=min(low[u],low[e[i]]);
}
if(dfn[u]==low[u]){
mk++;
while(inq[u]){
inq[st.top()]=0;
mkr[st.top()]=mk;
st.pop();
}
rt[mk]=u;
}
}
bool ck(int u,int pre){
if(dfn[u]) return false;
dfn[u]=1;
for(int i=head[u];i;i=net[i]){
if(mkr[u]!=mkr[e[i]]||e[i]==pre) continue;
if(!ck(e[i],u)) return false;
}
return true;
}
void dfs1(int u,int pre){//Take the max. of longest distance through children
for(int i=head[u];i;i=net[i]){
if(mkr[u]!=mkr[e[i]]||e[i]==pre) continue;
dfs1(e[i],u);
if(dp[e[i]][0]+1>dp[u][0]){
dp[u][1]=dp[u][0];
dp[u][0]=dp[e[i]][0]+1;
}
else dp[u][1]=max(dp[u][1],dp[e[i]][0]+1);
}
}
void dfs2(int u,int pre){//Propagate the longest distance through parent
for(int i=head[u];i;i=net[i]){
if(mkr[u]!=mkr[e[i]]||e[i]==pre) continue;
if(dp[e[i]][0]+1==dp[u][0]){
if(dp[u][1]+1>dp[e[i]][0]){
dp[e[i]][1]=dp[e[i]][0];
dp[e[i]][0]=dp[u][1]+1;
}
else dp[e[i]][1]=max(dp[e[i]][1],dp[u][1]+1);
}
else{
if(dp[u][0]+1>dp[e[i]][0]){
dp[e[i]][1]=dp[e[i]][0];
dp[e[i]][0]=dp[u][0]+1;
}
else dp[e[i]][1]=max(dp[e[i]][1],dp[u][0]+1);
}
dfs2(e[i],u);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
int u,v,w;
_for(i,1,m){
cin>>u>>v>>w;
add_edge(u,v);
if(w==2) add_edge(v,u);
}
_for(i,1,n) if(!dfn[i]) tarjan(i);
_for(i,1,n) dfn[i]=0;
_for(i,1,n) if(!dfn[i]&&(!ck(i,i))){
cout<<"Infinite";
return 0;
}
_for(i,1,n){
for(int j=head[i];j;j=net[j]){
if(mkr[i]!=mkr[e[j]]){
add_edge2(i,e[j]);
ein[mkr[e[j]]]++;
//cout<<i<<" "<<e[j]<<" "<<mkr[i]<<" "<<mkr[e[j]]<<endl;
}
}
}
//cout<<ein[1]<<endl;
//_for(i,1,mk) cout<<ein[i]<<endl;
_for(i,1,mk) if(!ein[i]) q.push(i);
while(!q.empty()){
u=q.front();q.pop();//cout<<rt[u]<<endl;
dfs1(rt[u],0);
dfs2(rt[u],0);
for(int i=head2[u];i;i=net2[i]){
ein[e2[i].mkv]--;
if(!ein[e2[i].mkv]) q.push(e2[i].mkv);
dp[e2[i].v][0]=max(dp[e2[i].v][0],dp[e2[i].u][0]+1);
}
}
int an=0;
//_for(i,1,mk) cout<<ein[i]<<endl;
_for(i,1,n) an=max(an,dp[i][0]);
//_for(i,1,n) cout<<dp[i][0]<<endl;
cout<<an;
return 0;
}