题意:缩点找最长链
#include <bits/stdc++.h>
using namespace std;
#define N 100005
int dp[N],vis[N],f[N];
vector<int>path[N],son[N];
stack<int>q;
int dep[N],low[N],tot,cnt;
void tarjan(int u)
{
dep[u]=low[u]=vis[u]=++tot;
q.push(u);
for(int i=0;i<path[u].size();i++){
int to=path[u][i];
if(!dep[to]){
tarjan(to);
low[u]=min(low[u],low[to]);
}
else if(vis[to])low[u]=min(low[u],dep[to]);
}
if(dep[u]!=low[u])return;
cnt++;
while(1){
int to=q.top();q.pop();
f[to]=cnt;
son[cnt].push_back(to);
vis[to]=0;
if(to==u)break;
}
}
int dfs(int x)
{
if(vis[x])return dp[x];
vis[x]=1;
for(int i=0;i<son[x].size();i++)
for(int j=0;j<path[son[x][i]].size();j++)
dp[x]=max(dp[x],dfs(f[path[son[x][i]][j]]));
return dp[x]+=son[x].size();
}
void init(int n){
for(int i=1;i<=n;i++)dp[i]=0,path[i].clear(),vis[i]=0,dep[i]=0,son[i].clear();
tot=cnt=1;
}
int main()
{
int m,n,u,to;
while(scanf("%d %d",&n,&m)!=EOF){
init(n);
while(m--){
scanf("%d %d",&u,&to);
if(u!=to)path[u].push_back(to);
}
int ans=1;
for(int i=1;i<=n;i++)
if(!dep[i])tarjan(i);
for(int i=1;i<=n;i++)
{
if(!vis[f[i]])dfs(f[i]);
ans=max(ans,dp[f[i]]);
}
printf("%d\n",ans);
}
return 0;
}