网络吞吐量(network)

题目

这里写图片描述

分析

过一遍spfa,把从点1到其他每一个点的最短路求出来,
接着递归把所有最短路径上的路径保留,其他的删掉。
对于保留的路径作为网络流的边,流量为无穷大,对于每个点拆点两个点之间的流量为吞吐量。
跑个网络流。

#include <fstream>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
const long long maxlongint=2147483647000000;
using namespace std;
long long dis[2100],a[600][600],f[2000][2000],d[600000],tot;
long long v[2100];
long long n,m,id;
long long spfa()
{
    long long i,j,l;
    dis[1]=0;
    d[1]=1;
    long long head=0,tail=1,k;
    while(head<tail)
    {
        head++;
        k=d[head];
        v[k]=true;
        for(i=1;i<=n;i++)
        {
            if(a[k][i]>0)
            {
                if(a[k][i]+dis[k]<dis[i])
                {
                    dis[i]=dis[k]+a[k][i];
                    if(v[i])
                    {
                        v[i]=false;
                        d[++tail]=i;
                    }
                }
            }
        }
    }
}
long long dg(long long x,long long v1)
{
    if(x==n) return 0;
    v[x]=false;
    for(long long i=2;i<=n;i++)
    {
        if(a[x][i]<maxlongint)
            if(v1+a[x][i]==dis[i])
            {
                f[x+n][i]=maxlongint;
                if(v[i])
                    dg(i,dis[i]); 
            }
    }
}
bool bfs()
{
    memset(dis,0,sizeof(dis));
    long long i,j,l;
    d[1]=1;
    long long head=0,tail=1,k;
    while(head<tail)
    {
        k=d[++head];
        for(i=2;i<=n+n;i++)
        {
            if(f[k][i]>0 && dis[i]==0)
            {
                dis[i]=dis[k]+1;
                d[++tail]=i;
            }
        }
    }
    if(dis[n+n])
        return true;
            else return false;
}
long long aug(long long x,long long y)
{
    if(x==n+n) return y;
    long long o;
    for(long long i=1;i<=n+n;i++)
    {
        if(f[x][i]>0 && dis[x]+1==dis[i])
        {
            o=aug(i,min(y,f[x][i]));
            if(o>0)
            {
                f[x][i]-=o;
                f[i][x]+=o;
                return o;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%lld%lld",&n,&m);
    long long i,j,k,l,x,y,z;
    for(i=1;i<=n;i++)
    {
        dis[i]=maxlongint;
        for(j=1;j<=n;j++)
        {
            a[i][j]=maxlongint;
        }
    }
    for(i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        if(x>y) 
        {
            j=x;
            x=y;
            y=j;
        }
        if(x==1) a[x][y]=min(a[x][y],z);else 
        if(y==n) a[x][y]=min(a[x][y],z);else a[y][x]=a[x][y]=min(a[x][y],z);
    }
    memset(v,true,sizeof(v));
    spfa();
    memset(v,true,sizeof(v));
    memset(f,0,sizeof(f));
    dg(1,0);
    long long ans,t=99;
    memset(v,0,sizeof(v));
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&f[i][i+n]);
        if(i==1 || i==n) f[i][i+n]=maxlongint;
    }
    ans=0;
    while(bfs())
    {
        ans+=aug(1,maxlongint);
    }
    cout<<ans;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/chen1352/p/9045318.html
今日推荐