歌名 - 歌手
0:00

    网络吞吐量(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;
    }
    
    posted @ 2018-05-16 12:18  无尽的蓝黄  阅读(775)  评论(0编辑  收藏  举报