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

【BZOJ3876】【Ahoi2014】支线剧情 有下界的最小费用最大流

时间:2015-01-22 23:27:31      阅读:463      评论:0      收藏:0      [点我收藏+]

标签:bzoj3876   ahoi2014   支线剧情   有下界的最小费用最大流   

#include <stdio.h>
int main()
{
	puts("转载请注明出处谢谢");
	puts("http://blog.csdn.net/vmurder/article/details/43025375");
}


【BZOJ2324】营救皮卡丘 这道题也是一道有下界的最小费用最大流。

我的题解地址:http://blog.csdn.net/vmurder/article/details/41378979


这道题其实就是模板题。

    我的处理方法就是把每条边拆一条流量为1的出来,然后费用为本来费用-inf。而在建图时可以把这些扣掉的inf加回来。可以证明这种方法至少在拓扑图上是不会被卡出负环的。


代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 500
#define M 31000
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3fll
using namespace std;
struct KSD
{
	int u,v,len,next;
	long long fee;
}e[M];
int head[N],cnt;
void add(int u,int v,int len,int fee)
{
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].len=len;
	e[cnt].fee=fee;
	e[cnt].next=head[u];
	head[u]=cnt;
}
int s,t;
long long dist[N];
int pre[N],lim[N];
bool in[N];
queue<int>q;
void spfa()
{
	memset(dist,0x3f,sizeof(dist));
	memset(lim,0,sizeof(lim));
	while(!q.empty())q.pop();
	int i,u,v;
	dist[s]=0,in[s]=1;
	lim[s]=inf;
	q.push(s);
	while(!q.empty())
	{
		u=q.front(),q.pop(),in[u]=0;
		for(i=head[u];i;i=e[i].next)
		{
			v=e[i].v;
			if(!e[i].len)continue;
			if(dist[v]>dist[u]+e[i].fee)
			{
				dist[v]=dist[u]+e[i].fee;
				lim[v]=min(e[i].len,lim[u]);
				pre[v]=i;

				if(!in[v])
				{
					in[v]=1;
					q.push(v);
				}
			}
		}
	}
	return ;
}
void handle(int flow)
{
	for(int i=pre[t];i;i=pre[e[i].u])
	{
		e[i].len-=flow;
		e[i^1].len+=flow;
	}
}
long long minfee;
int n,m;

void build()
{
	int i,j,k;
	int a,b,c;
	cnt=1;
	scanf("%d",&n);
	s=n+1,t=n+2;
	add(s,1,inf,0),add(1,s,0,0);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a);
		add(i,t,inf,0),add(t,i,0,0);
		while(a--)
		{
			scanf("%d%d",&b,&c);
			minfee+=inf;
			add(i,b,inf,c),add(b,i,0,-c);
			add(i,b,1,c-inf),add(b,i,0,inf-c);
		}
	}
	return ;
}
void checkedge()
{
	for(int u=1;u<=t;u++)
	{
		printf("From %d:",u);
		for(int i=head[u];i;i=e[i].next)
		{
			printf(" %d/%d/%d",e[i].v,e[i].len,e[i].fee);
		}
		puts("");
	}
	puts("");
}
int main()
{
	freopen("test.in","r",stdin);
	build();
	while(spfa(),dist[t]<INF)
	{
		minfee+=dist[t]*lim[t];
		handle(lim[t]);
	}
	cout<<minfee<<endl;
	return 0;
}


【BZOJ3876】【Ahoi2014】支线剧情 有下界的最小费用最大流

标签:bzoj3876   ahoi2014   支线剧情   有下界的最小费用最大流   

原文地址:http://blog.csdn.net/vmurder/article/details/43025375

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