zoj 2760

加油!看到了吧,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;
}


你可能感兴趣的:(zoj 2760)