加油!看到了吧,xsbailong,所有人都比你要努力的!!
/*
zoj_2760 最大流,最短路
floyd+最大流
依旧木有思路。。借用别人的思路:
先用floyd求出任意两点间的最短路长度,如果maz[s][i]+map[i][j]+maz[j][t]==maz[s][t]
(注:maz[i][j]指的是i到j之间的最短距离。map[i][j]为原图中i和j之间的直接距离)则
i-->j必为一条最短路的一部分则addedge(i,j,1);代表i到j这条边只能走一次。最后求一遍
s到t的最大流即可
代码不用多说,有思路的话很容易就过了,注意对角线数据不一定全0。
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <string.h>
#define inf 100000000
using namespace std;
int r[110][110];
int map[110][110];
int dist[110][110][2];
int pre[110];
int floyd( int n )
{
int i,j,k;
for( i=0;i<n;i++ )
for( j=0;j<n;j++ )
{
if( map[i][j]==-1 ) dist[i][j][0]=inf;
else dist[i][j][0]=map[i][j];
}
for( k=0;k<n;k++ )
{
for( i=0;i<n;i++ )
for( j=0;j<n;j++ )
{
dist[i][j][1]=dist[i][j][0];
if( dist[i][j][1]>dist[i][k][0]+dist[k][j][0] )
dist[i][j][1]=dist[i][k][0]+dist[k][j][0];
}
for( i=0;i<n;i++ )
for( j=0;j<n;j++ )
dist[i][j][0]=dist[i][j][1];
}
}
void build( int sta,int end,int n )
{
int i,j;
memset( r,0,sizeof(r) );
for( i=0;i<n;i++ )
for( j=0;j<n;j++ )
if( map[i][j]!=-1 && dist[sta][i][0]+map[i][j]+dist[j][end][0]==dist[sta][end][0] )
r[i][j]=1;
}
bool bfs( int sta,int end,int n )
{
int i;
bool flag[110];
queue <int>q;
memset( flag,0,sizeof(flag) );
q.push(sta); flag[sta]=1;
while( !q.empty() )
{
sta=q.front(); q.pop();
for( i=0;i<n;i++ )
if( !flag[i] && r[sta][i]>0 )
{
pre[i]=sta;
if( i==end ) return true;
q.push(i);
flag[i]=1;
}
}
return false;
}
int EdmondsKarp( int sta,int end,int n )
{
int mini,flow,i;
flow=0;
while( bfs( sta,end,n ) )
{
for( i=end;i!=sta;i=pre[i] )
{
r[ pre[i] ][i]-=1;
r[i][ pre[i] ]+=1;
}
flow++;
}
return flow;
}
int main()
{
int n,sta,end,i,j;
while( scanf( "%d",&n )!=EOF )
{
for( i=0;i<n;i++ )
for( j=0;j<n;j++ )
{
scanf( "%d",&map[i][j] );
if( i==j ) map[i][j]=0;
}
scanf( "%d%d",&sta,&end );
if( sta==end ) printf( "inf\n" );
else
{
floyd(n);
build( sta,end,n );
printf( "%d\n",EdmondsKarp( sta,end,n ) );
}
}
return 0;
}