hdu3639 Hawk-and-Chicken

强连通+反向图,

刚开始没想那么多,就按原来强连通的方法写,写到最后不知道该怎样写了,因为如果不进行特殊处理的话,每次搜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 }

 

你可能感兴趣的:(awk)