zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    python-常用数据类型
    python入门篇
    Vue 架构
    Bootstrap Web框架
    策略模式
    Java线程安全总结
    JVM中线程状态转换图
    java 多线程并发系列之 生产者消费者模式的两种实现
    JVM 垃圾回收器详解
    MyISAM和InnoDB索引实现对比
  • 原文地址:https://www.cnblogs.com/lcf-2000/p/6478035.html
Copyright © 2011-2022 走看看