强连通+反向图,

刚开始没想那么多,就按原来强连通的方法写,写到最后不知道该怎样写了,因为如果不进行特殊处理的话,每次搜in_deree[i]==0的点,然后把以它为尾的 有向边的  头结点的in_deree--;

但是感觉这样写出来会超时,  就没再接着写,上网搜了下, 发现需要一个反向图。。

自己又在纸上一划,感觉有思路了,,就给写出来了。。。

求出来强连通分量之后,把每一个强连通分量看成一个点,然后它有一个val值,表示它包含的点的个数。。

建立反向图, support最高的必定  存在于 入度为 0 的点之中。。

然后根据入度为0的一直深搜下去,找去最大的support就ok了。。。

代码:

View Code
  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 }

 

posted on 2011-04-21 13:32  奋斗青春  阅读(479)  评论(0编辑  收藏  举报