POJ 3272 Traffic
题意:有 n 个地点,已知这些点之间有 m条边,图是有个有向无环图,出度为0 的点唯一,即为 n点,问从入度为 0 的点到出度为 0 的点的所有路径中,经过次数最多的边,并求出最多经过的次数。
分析: 因为是有向无环图,可以正反向分别广搜一次,计算出所有点正反向的入度,枚举所有边弧尾的在正向搜索中的入度和弧头在反向搜索中的入度的乘积,找到最大值即为答案。
#include<stdio.h> #include<string.h> int g[5005][5005]; int d1[5005],d2[5005]; int q[5005]; int in[5005],out[5005]; struct node { int x,y; }e[50005]; int main() { int i,x,front,rear,res,n,m; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=m;i++){ scanf("%d%d",&e[i].x,&e[i].y); g[e[i].x][e[i].y]++; in[e[i].y]++; out[e[i].x]++; } front=rear=0; for(i=1;i<=n;i++) if(in[i]==0) { q[rear++]=i; d1[i]=1; } while(front<rear) { x=q[front++]; for(i=1;i<=n;i++) if(g[x][i]) { d1[i]+=g[x][i]*d1[x]; in[i]-=g[x][i]; if(in[i]==0) q[rear++]=i; } } front=rear=0; q[rear++]=n; d2[n]=1; while(front<rear) { x=q[front++]; for(i=1;i<=n;i++) if(g[i][x]) { d2[i]+=g[i][x]*d2[x]; out[i]-=g[i][x]; if(out[i]==0) q[rear++]=i; } } res=0; for(i=1;i<=m;i++) if(res<d1[e[i].x]*d2[e[i].y]) res=d1[e[i].x]*d2[e[i].y]; printf("%d\n",res); } return 0; }