poj 3272-Cow Traffic解题报告

求一个有向图中,从所有起点(入度为0)到终点(唯一,出度为0)经过的次数最多的边经过的次数,两次拓扑排序,一次向前求出所有起点到某个点的所有路径总数f[i],一次向后,求出某个点到终点的所有路径总数g[i],则对一条边(u,v),f[u]*g[v]即为边所需要经过的次数。

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define N 1005//数据范围没有题中描述的那么大……
 4 #define M 10005
 5 int map[N][N];
 6 int edge[M][2];
 7 int in[N],out[N],f[N],g[N];
 8 int que[N];
 9 void init()
10 {
11     memset(in,0,sizeof(in));
12     memset(out,0,sizeof(out));
13     memset(f,0,sizeof(f));
14     memset(g,0,sizeof(g));
15     memset(map,0,sizeof(map));
16 }
17 int main()
18 {
19     int n,m,i,j,fr,r,u,v,max;
20     scanf("%d%d",&n,&m);
21     init();
22     for(i=0;i<m;i++)
23     {
24         scanf("%d%d",&u,&v);
25         edge[i][0]=u,edge[i][1]=v;
26         map[u][v]++;
27         in[v]++;
28         out[u]++;
29     }
30     fr=r=0;
31     for(i=1;i<=n;i++)
32     {
33         if(in[i]==0)
34         {
35             que[r++]=i;
36             f[i]=1;
37         }
38     }
39     while(fr<r)
40     {
41         u=que[fr++];
42         for(i=1;i<=n;i++)
43         {
44             if(map[u][i])
45             {
46                 f[i]+=(map[u][i]*f[u]);
47                 in[i]-=map[u][i];
48                 if(in[i]==0)
49                 que[r++]=i;
50             }
51         }
52     }
53     fr=r=0;
54     que[r++]=n;
55     g[n]=1;
56     while(fr<r)
57     {
58         u=que[fr++];
59         for(i=1;i<=n;i++)
60         {
61             if(map[i][u])
62             {
63                 g[i]+=(map[i][u]*g[u]);
64                 out[i]-=map[i][u];
65                 if(out[i]==0)
66                 que[r++]=i;
67             }
68         }
69     }
70     max=0;
71     for(i=1;i<=m;i++)
72     {
73         if(max<f[edge[i][0]]*g[edge[i][1]])
74         max=f[edge[i][0]]*g[edge[i][1]];
75     }
76     printf("%d\n",max);
77     return 0;
78 }

 

posted @ 2012-07-27 11:13  zhenhai  阅读(242)  评论(0)    收藏  举报