【UVA11324】The Largest Clique (SCC)

题意:

  给一张有向图G,求一个结点数最大的结点集,使得该结点中任意两个结点 u 和 v满足:要么 u 可以到达 v, 要么 v 可以到达 u(u 和 v 相互可达也可以)。

分析:

  Tarjan求SCC缩点,SCC的节点数为新点点权,然后求DAG上权最大的的路径。

代码如下:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #define Maxn 1010
 5 #define Maxm 50010
 6 
 7 struct node
 8 {
 9     int x,y,next;
10 }t[Maxm];
11 
12 int first[Maxn],dfn[Maxn],low[Maxn],sta[Maxn],scc[Maxn],sum[Maxn];
13 bool bj[Maxn],bj2[Maxn],map[Maxn][Maxn];
14 int cnt,sl,cl;
15 
16 int mymin(int x,int y) {return x<y?x:y;}
17 int mymax(int x,int y) {return x>y?x:y;}
18 
19 void ffind(int x)
20 {
21     dfn[x]=low[x]=++cnt;
22     sta[++sl]=x;
23     for(int i=first[x];i;i=t[i].next)
24     {
25         int y=t[i].y;
26         if(dfn[y]==0)
27         {
28             ffind(y);
29             low[x]=mymin(low[x],low[y]);
30         }
31         else if(scc[y]==0) low[x]=mymin(low[x],dfn[y]);
32     }
33     if(dfn[x]==low[x])
34     {
35         cl++;
36         while(1)
37         {
38             int z=sta[sl--];
39             scc[z]=cl;
40             sum[cl]++;
41             if(z==x) break;
42         }
43     }
44 }
45 
46 int dfs(int x)
47 {
48     int ans=0;
49     bj[x]=1;
50     for(int i=1;i<=cl;i++) if(map[x][i]==1&&bj[i]==0)
51      ans=mymax(ans,dfs(i));
52     ans+=sum[x];
53     bj[x]=0;
54     return ans;
55 }
56 
57 int main()
58 {
59     int T;
60     scanf("%d",&T);
61     while(T--)
62     {
63         int n,m,ans=0;
64         scanf("%d%d",&n,&m);
65         memset(first,0,sizeof(first));
66         memset(dfn,0,sizeof(dfn));
67         memset(sum,0,sizeof(sum));
68         memset(bj,0,sizeof(bj));
69         memset(map,0,sizeof(map));
70         memset(scc,0,sizeof(scc));
71         cnt=0;sl=0;cl=0;
72         for(int i=1;i<=m;i++)
73         {
74             int x,y;
75             scanf("%d%d",&t[i].x,&t[i].y);
76             t[i].next=first[t[i].x];first[t[i].x]=i;
77         }
78         for(int i=1;i<=n;i++) if(dfn[i]==0) ffind(i);
79         for(int i=1;i<=m;i++) if(scc[t[i].x]!=scc[t[i].y]) map[scc[t[i].x]][scc[t[i].y]]=1;
80         for(int i=1;i<=cl;i++) ans=mymax(ans,dfs(i));
81         printf("%d
",ans);
82     }
83     return 0;
84 }
UVA11324

2016-03-17 16:54:20

原文地址:https://www.cnblogs.com/Konjakmoyu/p/5288068.html