首页 > 代码库 > BZOJ 3876 【AHOI2014】 支线剧情

BZOJ 3876 【AHOI2014】 支线剧情

题目链接:支线剧情

  这道题就是一道裸裸的上下界网络流……只不过这道题边带了权,那么建出图之后跑费用流即可。

  首先需要新建超级源\(S\)和超级汇\(T\)。对于这道题,对于一条边\((u,v,z)\),我们从\(S\)向\(v\)连一条容量为\(1\),费用为\(z\)的边,保证下界;从\(u\)向\(T\)连一条容量为\(1\),费用为\(0\)的边,也是用来保证下界的。由于没有上界,所以直接从\(u\)向\(v\)连一条容量为\(INF\),费用为\(z\)的边即可。

  注意这道题可以在任意一个点重新开始,所以等于除\(1\)号点之外所有的点都可能成为汇点,所以连边的时候需要注意以下。也就是说,除了\(1\)号点之外的所有点,都要向\(1\)连一条容量为\(INF\),费用为\(0\)的边来保证流量平衡。

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 310
#define maxm 50010
#define INF (1<<29)

using namespace std;
typedef long long llg;

int n,S,T,c[maxm],f[maxm],ans;
int head[maxn],next[maxm],to[maxm],tt=1;
int d[maxn],dep[maxn],fr[maxn];
bool w[maxn];

int getint(){
	int w=0;bool q=0;
	char c=getchar();
	while((c>‘9‘||c<‘0‘)&&c!=‘-‘) c=getchar();
	if(c==‘-‘) c=getchar(),q=1;
	while(c>=‘0‘&&c<=‘9‘) w=w*10+c-‘0‘,c=getchar();
	return q?-w:w;
}

void link(int x,int y,int z,int o){
	to[++tt]=y;next[tt]=head[x];head[x]=tt;
	to[++tt]=x;next[tt]=head[y];head[y]=tt;
	c[tt-1]=z; f[tt-1]=o; f[tt]=-o;
}

bool spfa(){
	for(int i=1;i<=T;i++) dep[i]=INF;
	int ld=0,rd=0; dep[d[rd++]=S]=0;
	while(ld!=rd){
		int u=d[ld++]; w[u]=0; if(ld==maxn) ld=0;
		for(int i=head[u],v;v=to[i],i;i=next[i])
			if(c[i] && dep[v]>dep[u]+f[i]){
				dep[v]=dep[u]+f[i]; fr[v]=i;
				if(!w[v]){
					w[v]=1;
					if(dep[v]<=dep[d[ld]]) ld--,ld+=maxn,ld%=maxn,d[ld]=v;
					else d[rd++]=v,rd%=maxn;
				}
			}
	}
	return dep[T]!=INF;
}

int get(){
	int now=INF,ans=0;
	for(int u=T;u!=S;u=to[fr[u]^1]) now=min(now,c[fr[u]]),ans+=f[fr[u]];
	for(int u=T;u!=S;u=to[fr[u]^1]) c[fr[u]]-=now,c[fr[u]^1]+=now;
	return now*ans;
}

int main(){
	File("a");
	n=getint(); S=n+1,T=n+2;
	for(int i=1,x,u,z;i<=n;i++){
		x=getint();
		if(i!=1) link(i,1,INF,0);
		if(x) link(i,T,x,0);
		while(x--){
			u=getint(); z=getint();
			link(i,u,INF,z),link(S,u,1,z);
		}
	}
	while(spfa()) ans+=get();
	printf("%d",ans);
	return 0;
}

BZOJ 3876 【AHOI2014】 支线剧情