网络吞吐量(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;
}
原文地址:https://www.cnblogs.com/chen1352/p/9045318.html