uva 11324

Problem B: The Largest Clique

Given a directed graph G, consider the following transformation. First, create a new graph T(G) to have the same vertex set as G. Create a directed edge between two vertices u and v in T(G) if and only if there is a path between u and v in G that follows the directed edges only in the forward direction. This graph T(G) is often called the transitive closure of G.

We define a clique in a directed graph as a set of vertices U such that for any two vertices u and v in U, there is a directed edge either from u to v or from v to u (or both). The size of a clique is the number of vertices in the clique.

The number of cases is given on the first line of input. Each test case describes a graph G. It begins with a line of two integers n and m, where 0 ≤ n ≤ 1000 is the number of vertices of G and 0 ≤ m ≤ 50,000 is the number of directed edges of G. The vertices of G are numbered from 1 to n. The following m lines contain two distinct integers u and v between 1 and n which define a directed edge from u to v in G.

For each test case, output a single integer that is the size of the largest clique in T(G).

Sample input

1
5 5
1 2
2 3
3 1
4 1
5 2

Output for sample input

4

Zachary Friggstad

 

强连通分量缩点成DAG,求点集最大的路径。

 

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <stack>
  6 #include <vector>
  7 
  8 using namespace std;
  9 
 10 const int MAX_N = 1005;
 11 const int edge = 5e4 + 5;
 12 int N,M;
 13 int low[MAX_N],pre[MAX_N],cmp[MAX_N];
 14 int first[MAX_N],Next[edge],v[edge];
 15 int ind[MAX_N],oud[MAX_N];
 16 int dfs_clock,scc_cnt;
 17 int dep[MAX_N];
 18 int num[MAX_N];
 19 stack <int > S;
 20 vector<int > G[MAX_N];
 21 
 22 
 23 void dfs(int u) {
 24         pre[u] = low[u] = ++dfs_clock;
 25         S.push(u);
 26         for(int e = first[u]; e != -1; e = Next[e]) {
 27                 if(!pre[ v[e] ]) {
 28                         dfs(v[e]);
 29                         low[u] = min(low[u],low[ v[e] ]);
 30                 } else if( !cmp[ v[e] ]) {
 31                         low[u] = min(low[u],pre[ v[e] ]);
 32                 }
 33         }
 34 
 35         if(pre[u] == low[u]) {
 36                 ++scc_cnt;
 37                 for(;;) {
 38                         int x = S.top(); S.pop();
 39                         cmp[x] = scc_cnt;
 40                         num[scc_cnt]++;
 41                         if(x == u) break;
 42                 }
 43         }
 44 }
 45 void scc() {
 46         dfs_clock = scc_cnt = 0;
 47         memset(cmp,0,sizeof(cmp));
 48         memset(pre,0,sizeof(pre));
 49 
 50         for(int i = 1; i <= N; ++i) if(!pre[i]) dfs(i);
 51 }
 52 
 53 void dfs1(int u) {
 54         pre[u] = 1;
 55         for(int i = 0; i < G[u].size(); ++i) {
 56                 if(!pre[ G[u][i] ]) {
 57                         dfs1( G[u][i] );
 58                 }
 59                 dep[u] = max(dep[u],dep[ G[u][i] ] + num[u]);
 60         }
 61 }
 62 
 63 void solve() {
 64         scc();
 65         for(int i = 1; i <= scc_cnt; ++i) G[i].clear();
 66         for(int i = 1; i <= scc_cnt; ++i) dep[i] = num[i];
 67 
 68         for(int i = 1; i <= N; ++i) {
 69                 for(int e = first[i]; e != -1; e = Next[e]) {
 70                         if(cmp[i] == cmp[ v[e] ]) continue;
 71                         G[ cmp[i] ].push_back(cmp[ v[e] ]);
 72                 }
 73         }
 74 
 75         memset(pre,0,sizeof(pre));
 76         for(int i = 1; i <= scc_cnt; ++i) {
 77                 if(!pre[i]) dfs1(i);
 78         }
 79 
 80         int ans = 0;
 81         for(int i = 1; i <= scc_cnt; ++i) {
 82                 ans = max(ans,dep[i]);
 83         }
 84 
 85         printf("%d\n",ans);
 86 
 87 }
 88 
 89 void add_edge(int id,int u) {
 90         int e = first[u];
 91         Next[id] = e;
 92         first[u] = id;
 93 }
 94 int main()
 95 {
 96     //freopen("sw.in","r",stdin);
 97     int t;
 98     scanf("%d",&t);
 99     while(t--) {
100             scanf("%d%d",&N,&M);
101             for(int i = 1; i <= N; ++i) first[i] = -1;
102             memset(num,0,sizeof(num));
103 
104             for(int i = 1; i <= M; ++i) {
105                     int u;
106                     scanf("%d%d",&u,&v[i]);
107                     add_edge(i,u);
108             }
109 
110             solve();
111     }
112     //cout << "Hello world!" << endl;
113     return 0;
114 }
View Code

 

转载于:https://www.cnblogs.com/hyxsolitude/p/3700877.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值