UVa11324 The Largest Clique(强连通分量+缩点+记忆化搜索)

题目给一张有向图G,要在其传递闭包T(G)上删除若干点,使得留下来的所有点具有单连通性,问最多能留下几个点。

其实这道题在T(G)上的连通性等同于在G上的连通性,所以考虑G就行了。

那么问题就简单了,强连通分量缩点,强连通分量必定要一起留下,从入度0到出度0的强连通分量找到一条包含最多点的通路即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define MAXN 1111
 6 #define MAXM 55000
 7 struct Edge{
 8     int u,v,next;
 9 }edge[MAXM];
10 int NE,head[MAXN];
11 void addEdge(int u,int v){
12     edge[NE].u=u; edge[NE].v=v; edge[NE].next=head[u];
13     head[u]=NE++;
14 }
15 int top,stack[MAXN];
16 bool instack[MAXN];
17 int dn,dfn[MAXN],low[MAXN];
18 int bn,belong[MAXN],size[MAXN];
19 void tarjan(int u){
20     dfn[u]=low[u]=++dn;
21     stack[++top]=u; instack[u]=1;
22     for(int i=head[u]; i!=-1; i=edge[i].next){
23         int v=edge[i].v;
24         if(dfn[v]==0){
25             tarjan(v);
26             low[u]=min(low[u],low[v]);
27         }else if(instack[v]){
28             low[u]=min(low[u],dfn[v]);
29         }
30     }
31     if(low[u]==dfn[u]){
32         int v; ++bn;
33         do{
34             v=stack[top--];
35             instack[v]=0;
36             belong[v]=bn;
37             ++size[bn];
38         }while(u!=v);
39     }
40 }
41 int d[MAXN];
42 int dfs(int u){
43     if(d[u]) return d[u];
44     int res=0;
45     for(int i=head[u]; i!=-1; i=edge[i].next){
46         int v=edge[i].v;
47         res=max(res,dfs(v));
48     }
49     return d[u]=res+size[u];
50 }
51 int main(){
52     int t,n,m,a,b;
53     scanf("%d",&t);
54     while(t--){
55         scanf("%d%d",&n,&m);
56         NE=0;
57         memset(head,-1,sizeof(head));
58         while(m--){
59             scanf("%d%d",&a,&b);
60             addEdge(a,b);
61         }
62         top=dn=bn=0;
63         memset(dfn,0,sizeof(dfn));
64         memset(instack,0,sizeof(instack));
65         memset(size,0,sizeof(size));
66         for(int i=1; i<=n; ++i){
67             if(dfn[i]==0) tarjan(i);
68         }
69         int tmp=NE; NE=0;
70         memset(head,-1,sizeof(head));
71         for(int i=0; i<tmp; ++i){
72             int u=belong[edge[i].u],v=belong[edge[i].v];
73             if(u==v) continue;
74             addEdge(u,v);
75         }
76         memset(d,0,sizeof(d));
77         int res=0;
78         for(int i=1; i<=bn; ++i){
79             res=max(res,dfs(i));
80         }
81         printf("%d\n",res);
82     }
83     return 0;
84 }

 

posted @ 2016-02-10 23:20  WABoss  阅读(195)  评论(0编辑  收藏  举报