强连通+反向图,
刚开始没想那么多,就按原来强连通的方法写,写到最后不知道该怎样写了,因为如果不进行特殊处理的话,每次搜in_deree[i]==0的点,然后把以它为尾的 有向边的 头结点的in_deree--;
但是感觉这样写出来会超时, 就没再接着写,上网搜了下, 发现需要一个反向图。。
自己又在纸上一划,感觉有思路了,,就给写出来了。。。
求出来强连通分量之后,把每一个强连通分量看成一个点,然后它有一个val值,表示它包含的点的个数。。
建立反向图, support最高的必定 存在于 入度为 0 的点之中。。
然后根据入度为0的一直深搜下去,找去最大的support就ok了。。。
代码:
1 # include<stdio.h> 2 # include<string.h> 3 # define N 5005 4 # define M 30005 5 struct node{ 6 int from,to,next; 7 }edge1[M],edge2[M],edge[N]; 8 int visit1[N],visit2[N],visit[N],head1[N],head2[N],head[N]; 9 int Belong[N],T[N],ans[N],val[N],in_degree[N],tol1,tol2,tol,Bcnt,Tcnt,sum; 10 void add(int a,int b) 11 { 12 edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++; 13 edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++; 14 } 15 void add1(int a,int b) 16 { 17 edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++; 18 } 19 void dfs1(int x) 20 { 21 int i; 22 visit1[x]=1; 23 for(i=head1[x];i!=-1;i=edge1[i].next) 24 if(visit1[edge1[i].to]==0) dfs1(edge1[i].to); 25 T[Tcnt++]=x; 26 } 27 void dfs2(int x) 28 { 29 int i; 30 visit2[x]=1; 31 val[Bcnt]++; 32 Belong[x]=Bcnt; 33 for(i=head2[x];i!=-1;i=edge2[i].next) 34 if(visit2[edge2[i].to]==0) dfs2(edge2[i].to); 35 } 36 void dfs(int x) 37 { 38 int i,v; 39 visit[x]=1; 40 sum+=val[x]; 41 for(i=head[x];i!=-1;i=edge[i].next) 42 { 43 v=edge[i].to; 44 if(visit[v]==0) dfs(v); 45 } 46 } 47 int main() 48 { 49 int i,n,m,x,y,a,b,t,ncase,max,flag; 50 scanf("%d",&ncase); 51 for(t=1;t<=ncase;t++) 52 { 53 scanf("%d%d",&n,&m); 54 tol1=tol=tol2=0; 55 Bcnt=Tcnt=0; 56 for(i=0;i<n;i++) 57 { 58 head[i]=head1[i]=head2[i]=-1; 59 visit1[i]=visit2[i]=0; 60 val[i]=0; 61 } 62 while(m--) 63 { 64 scanf("%d%d",&a,&b); 65 add(a,b); 66 } 67 for(i=0;i<n;i++) 68 if(visit1[i]==0) dfs1(i); 69 for(i=Tcnt-1;i>=0;i--) 70 { 71 if(visit2[T[i]]==0) 72 { 73 dfs2(T[i]); 74 Bcnt++; 75 } 76 } 77 for(i=0;i<Bcnt;i++) 78 in_degree[i]=0; 79 for(i=0;i<tol1;i++) 80 { 81 x=Belong[edge1[i].from]; 82 y=Belong[edge1[i].to]; 83 if(x!=y) 84 { 85 in_degree[x]++; 86 add1(y,x);/*建立反向图*/ 87 } 88 } 89 max=-1; 90 memset(ans,-1,sizeof(ans)); 91 for(i=0;i<Bcnt;i++) 92 { 93 if(in_degree[i]==0) 94 { 95 sum=0; 96 memset(visit,0,sizeof(visit)); 97 dfs(i); 98 ans[i]=sum-1; 99 if(ans[i]>max) max=ans[i]; 100 } 101 } 102 printf("Case %d: %d\n",t,max); 103 flag=0; 104 for(i=0;i<n;i++) 105 if(ans[Belong[i]]==max) 106 { 107 if(flag==0) {flag=1;printf("%d",i);} 108 else printf(" %d",i); 109 } 110 printf("\n"); 111 } 112 return 0; 113 }