- a到b,b到a,ab互相到达。这三个条件满足一个即可。那么我们先tarjan缩点,把ab互相到达的记录下来,让这个图变成一个有向无环图。
- 之后分别以各个点为起点,求最长直径即可。求出最大值来。
-
-
-
- #include <iostream>
- #include <stack>
- #include <vector>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- const int maxn = 1e3 + 10;
- int low[maxn],pre[maxn],sccno[maxn];
- int scc_cnt,dfs_colok;
- stack<int> s;
- vector<int> G[maxn],mp[maxn];
- void dfs(int u){
- low[u] = pre[u] = ++dfs_colok;
- s.push(u);
- for (int i = 0;i < G[u].size();++i){
- int v = G[u][i];
- if (!pre[v]){
- dfs(v);
- low[u] = min(low[v],low[u]);
- }else if (!sccno[v]) low[u] = min(low[u],pre[v]);
- }
- if (low[u] == pre[u]){
- scc_cnt++;
- for (;;){
- int x = s.top();
- s.pop();
- sccno[x] = scc_cnt;
- if (x == u) break;
- }
- }
- }
- void find_scc(int n){
- dfs_colok = scc_cnt = 0;
- memset(sccno, 0, sizeof sccno);
- memset(pre, 0,sizeof pre);
- for (int i = 0;i < n;i++)
- if (!pre[i]) dfs(i);
- }
- int val[maxn];
- void build(int n){
- for (int i = 1;i <= scc_cnt;i++)
- mp[i].clear();
- memset(val, 0,sizeof val);
- for (int i = 0;i < n;i++){
- val[sccno[i]]++;
- // cout << val[sccno[i]] << endl;
- }
- for (int i = 0;i < n;i++){
- for (int j = 0;j < G[i].size();j++){
- int v = G[i][j];
- if (sccno[i] != sccno[v]){
- mp[sccno[i]].push_back(sccno[v]);
- }
- }
- }
- }
- int dp[maxn];
- int search(int u) //求u为起点的长度
- {
- if (dp[u] != -1) return dp[u]; //如果u已经搜完了,直接返回u的长度
- dp[u] = val[u]; //u首先等于他自己的长度,也就是缩点时,他自身包含的点数
- for (int i = 0;i < mp[u].size();i++){ //遍历所有的点
- int v = mp[u][i]; //对于和u相连的点v
- dp[u] = max(dp[u],search(v) + val[u]); //u的长度=max(他自身,v的长度+他自己的长度)
- }
- // cout << dp[u] << endl;
- return dp[u];
- }
- int main(){
- // freopen("in.txt","r",stdin);
- // freopen("out","w",stdout);
- int n,m,t;
- scanf("%d",&t);
- while(t--){
- scanf("%d%d",&n,&m);
- for (int i = 0;i < n;i++)
- G[i].clear();
- int a,b;
- for (int i = 1;i <= m;i++){
- scanf("%d%d",&a,&b);
- a--;
- b--;
- G[a].push_back(b);
- }
- find_scc(n);
- // cout << "scc_cnt = " << scc_cnt << endl;
- build(n);
- memset(dp, -1,sizeof dp);
- int ans = 0;
- // for (int i = 1;i <= scc_cnt;i++)
- for (int i = 0;i < n;i++)
- ans = max(ans,search(sccno[i]));
- printf("%d\n", ans);
- }
- return 0;
- }