码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj-3931 网络吞吐量

时间:2015-06-25 09:05:43      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:bzoj   dijkstra   网络流   

题意:

给出一个n个结点的无向图,每个结点有一个吞吐量;

规则是数据包传递一定按照最短路,求1到n的网络吞吐量;


题解:
正如黄学长所说,此题题意即题解;

但是还是有几点需要注意的;

最短路是dij还是spfa都可以,但是为了建图需要记录一下路径;

如果用链式前向星可以将所有用来更新的边存下来建图;

但是用vector或者邻接矩阵(不知道能不能过)存边就不能实现;

我是用一个vector数组上面挂链;

拓扑队列扫一遍加边,复杂度挺低就过了;

然后拆点建图就没什么说的了;

最短路和流量都要开long long,第一个和最后一个点的吞吐量不用计入;



代码:


#include<queue>
#include<vector>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define pr pair<int,int>
#define N 600
#define M 210000
using namespace std;
typedef long long ll;
queue<int>q;
priority_queue<pr,vector<pr >,greater<pr > >poq;
vector<int>to[N],pre[N];
vector<ll>val[N];
int head[N<<1],next[M],T[M],n,tot=1;
ll dis[N<<1],flow[M];
bool vis[N];
void add(int x,int y,ll fl)
{
	T[++tot]=y,next[tot]=head[x],head[x]=tot,flow[tot]=fl;
	T[++tot]=x,next[tot]=head[y],head[y]=tot,flow[tot]=0;
}
void dij()
{
	memset(dis,0x3f,sizeof(dis));
	dis[1]=0;
	poq.push(pr(0,1));
	int x,y,i;
	while(!poq.empty())
	{
		x=poq.top().second,poq.pop();
		if(vis[x])	continue;
		vis[x]=1;
		for(i=0;i<to[x].size();i++)
		{
			if(!vis[y=to[x][i]])
			{
				if(dis[y]>dis[x]+val[x][i])
				{
					dis[y]=dis[x]+val[x][i];
					poq.push(pr(dis[y],y));
					pre[y].clear();
					pre[y].push_back(x);
				}
				else if(dis[y]==dis[x]+val[x][i])
					pre[y].push_back(x);
			}
		}
	}
}
bool bfs()
{
	memset(dis,-1,sizeof(dis));
	dis[3]=0;
	q.push(3);
	int x,y,i;
	while(!q.empty())
	{
		x=q.front(),q.pop();
		for(i=head[x];i;i=next[i])
		{
			if(flow[i]>0&&dis[y=T[i]]<0)
			{
				dis[y]=dis[x]+1;
				q.push(y);
			}
		}
	}
	return dis[n<<1]>=0;
}
ll dfs(int x,ll k)
{
	if(x==(n<<1))	return k;
	int y,i;
	ll j,ret=0;
	for(i=head[x];i;i=next[i])
	{
		if(flow[i]>0&&dis[y=T[i]]==dis[x]+1)
		{
			j=dfs(y,min(flow[i],k-ret));
			flow[i]-=j,flow[i^1]+=j;
			ret+=j;
			if(k==ret)	return ret;
		}
	}
	return ret;
}
int main()
{
	int m,i,j,k,x,y;
	ll v,ans;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%lld",&x,&y,&v);
		to[x].push_back(y),val[x].push_back(v);
		to[y].push_back(x),val[y].push_back(v);
	}
	dij();
	q.push(n);
	memset(vis,0,sizeof(vis));
	while(!q.empty())
	{
		x=q.front(),q.pop();
		for(i=0;i<pre[x].size();i++)
		{
			y=pre[x][i];
			add(y<<1|1,x<<1,0x3f3f3f3f3f3f3f3fll);
			if(!vis[y])
				vis[y]=1,q.push(y);
		}
	}
	for(i=1;i<=n;i++)
		scanf("%lld",&v),
		add(i<<1,i<<1|1,v);
	ans=0;
	while(bfs())
		ans+=dfs(3,0x3f3f3f3f3f3f3f3fll);
	printf("%lld",ans);
	return 0;
}


bzoj-3931 网络吞吐量

标签:bzoj   dijkstra   网络流   

原文地址:http://blog.csdn.net/ww140142/article/details/46627329

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!