1 /*UVA 11324强连通分量缩点+DAG上最长路(不明白算法为什么正确ing) 2 主要是为了练习缩点和GAD 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <math.h> 8 #include <ctype.h> 9 #include <string> 10 #include <iostream> 11 #include <sstream> 12 #include <vector> 13 #include <queue> 14 #include <stack> 15 #include <map> 16 #include <list> 17 #include <set> 18 #include <algorithm> 19 #define INF 0x3f3f3f3f 20 #define LL long long 21 #define eps 1e-7 22 #define maxn 1100 23 using namespace std; 24 25 //scc_cnt是计数器 26 //sccno[i]是i属于的分量 27 //注意scc不像bcc,分量间是没有公共点的 28 29 int t,n,m; 30 31 int pre[maxn] ,sccno[maxn] , low[maxn], dfs_clock , scc_cnt; 32 stack<int>S; 33 vector<int>G[maxn] ,scc[maxn]; 34 void dfs(int u){ 35 low[u] = pre[u] = ++dfs_clock; 36 S.push(u); 37 int ecnt = G[u].size(); 38 for(int i=0;i<ecnt ; i++){ 39 int v = G[u][i]; 40 if(!pre[v]){ 41 dfs(v); 42 low[u] = min(low[u] , low[v]); 43 } 44 else if(!sccno[v]){ 45 low[u] = min(low[u] , pre[v]); 46 } 47 } 48 if(low[u] == pre[u]){ 49 scc[++scc_cnt].clear(); 50 while(true){ 51 int x = S.top(); S.pop(); 52 sccno[x] = scc_cnt; 53 scc[scc_cnt].push_back(x); 54 if(x == u) break; 55 } 56 } 57 } 58 void find_scc(int n){ 59 memset(pre ,0 ,sizeof(pre)); 60 memset(sccno ,0 ,sizeof(sccno)); 61 dfs_clock = scc_cnt = 0; 62 for(int i=1;i<=n;i++){ 63 if(!pre[i]) dfs(i); 64 } 65 } 66 67 bool G1[maxn][maxn];//新图的邻接矩阵,方便判断 68 void BuiltNG()//建立缩点后的新的DAG图 69 { 70 memset(G1,0,sizeof(G1)); 71 for(int i=1;i<=n;i++)//枚举原先的每条边 72 { 73 for(int j=0;j<G[i].size();j++) 74 { 75 int u=sccno[i],v=sccno[G[i][j]]; 76 if (u!=v) G1[u][v]=true; 77 } 78 } 79 return ; 80 } 81 int d[maxn]; 82 int dp(int u)//记忆化搜索求GAD上的最长路,很长时间没写了,需要复习啊 83 { 84 int &ans = d[u]; 85 if (ans!=-1) return ans; 86 ans=0; 87 for(int i=1;i<=scc_cnt;i++) 88 { 89 if (G1[u][i]) ans=max(ans,dp(i)); 90 } 91 ans+=scc[u].size(); 92 return ans; 93 } 94 int solve() 95 { 96 int mx=0; 97 memset(d,-1,sizeof(d)); 98 for(int i=1;i<=scc_cnt;i++) 99 { 100 mx=max(mx,dp(i)); 101 } 102 return mx; 103 } 104 int main() 105 { 106 cin>>t; 107 while(t--) 108 { 109 cin>>n>>m; 110 for(int i=1;i<=n;i++) G[i].clear(); 111 for(int i=1;i<=m;i++) 112 { 113 int u,v; 114 cin>>u>>v; 115 G[u].push_back(v); 116 } 117 find_scc(n); 118 BuiltNG(); 119 cout<<solve()<<endl; 120 121 } 122 }