拓扑排序之五

//poj 3272 Cow Traffic

//求出由入度为0的源点到汇点的所有路径中使用最频繁那条边总共使用的次数
//f[i] 为入度为0的点到结点i的路径条数, g[i]为结点i到N的路径条数
//枚举每个边(s为始点,t为终点),则所有边的f[s]*g[t]的最大值即为答案

#include
<iostream> //拓扑排序
#include<deque>
using namespace std;
int n,m,table[5002][5002],side[50002][2];
int f[5002],g[5002],in[5002],out[5002];
deque
<int> pre,post;
int main()
{
cin
>>n>>m;
for(int i=0;i<m;++i)
{
cin
>>side[i][0]>>side[i][1];
in[side[i][1]]++; //有重边,如果用邻接表就不必考虑重边的问题了
out[side[i][0]]++;
table[side[i][
0]][side[i][1]]++;
}
for(int i=1;i<=n;++i)
if(in[i]==0) //可能有多个源点
{
pre.push_back(i);
f[i]
=1;
}
while(!pre.empty())
{
for(int i=1;i<=n;++i)
if(table[pre.front()][i]>0)
{
f[i]
+=table[pre.front()][i]*f[pre.front()]; //重边不能忽略掉,有m次重边就是m条路径数
in[i]-=table[pre.front()][i];
if(in[i]==0)
pre.push_back(i);

}
pre.pop_front();
}
post.push_back(n);
//汇点唯一:the barn is at intersection number N
g[n]=1;
while(!post.empty())
{
for(int i=1;i<=n;++i)
if(table[i][post.front()]>0)
{
g[i]
+=table[i][post.front()]*g[post.front()];
out[i]-=table[i][post.front()];
if(out[i]==0)
post.push_back(i);

}
post.pop_front();
}
int s=0;
for(int i=0;i<m;++i)
s
=max(s,f[side[i][0]]*g[side[i][1]]);
cout
<<s<<endl;
return 0;
}

  

posted on 2011-08-22 09:17  sysu_mjc  阅读(110)  评论(0编辑  收藏  举报

导航