zoukankan      html  css  js  c++  java
  • BZOJ 1834 ZJOI2010 network 网络扩容

    1834: [ZJOI2010]network 网络扩容

    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 3735  Solved: 2001
    [Submit][Status][Discuss]

    Description

    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。
    求: 
    1、在不扩容的情况下,1到N的最大流; 
    2、将1到N的最大流增加K所需的最小扩容费用。

    Input

    第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 
    接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
    N<=1000,M<=5000,K<=10

    Output

    输出文件一行包含两个整数,分别表示问题1和问题2的答案。

    Sample Input

    5 8 2
    1 2 5 8
    2 5 9 9
    5 1 6 2
    5 1 1 8
    1 2 8 7
    2 5 4 9
    1 2 1 1
    1 4 2 1

    Sample Output

    13 19

    HINT

     

    Source

    大水提,第一问就是最大流,dinic跑一下

    第二问,我们在残量网络上进行建图,在题目给的那些边都进行连边,流量inf,费用为题目给的费用

    dinic跑完的剩下边不用动,费用为0即可,s向1连一条流量为k,费用为0的边  跑一下最小费用最大流即可

    #include <bits/stdc++.h>
    #define ll long long
    #define inf 1e9+10
    using namespace std;
    inline int read(){
    	int x=0;int f=1;char ch=getchar();
    	while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    	while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    const int MAXN=1e5+10;
    struct node{
    	int y,next,back,flow,w;
    }e[MAXN];
    int len,linkk[MAXN],head,tail,level[1100],s,t,n,m,x[MAXN],y[MAXN],f[MAXN],c[MAXN],dis[1100],ans,vis[1100],q[MAXN],k;
    inline void insert(int x,int y,int f,int c){
    	e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;e[len].flow=f;e[len].back=len+1;e[len].w=c;
    	e[++len].y=x;e[len].next=linkk[y];linkk[y]=len;e[len].flow=0;e[len].back=len-1;e[len].w=-c;
    }
    namespace dinicc{
    	inline bool getlevel(){
    		head=tail=0;
    		memset(level,-1,sizeof(level));
    		level[s]=0;q[++tail]=s;
    		while(head<tail){
    			int tn=q[++head];
    			for(int i=linkk[tn];i;i=e[i].next){
    				if(level[e[i].y]==-1&&e[i].flow){
    					level[e[i].y]=level[tn]+1;
    					q[++tail]=e[i].y;
    				}
    			}
    		}
    		return level[t]>=0;
    	}
    	inline int getmaxflow(int x,int flow){
    		if(x==t) return flow;
    		int f=0,d;
    		for(int i=linkk[x];i;i=e[i].next){
    			if(e[i].flow&&level[e[i].y]==level[x]+1){
    				if(d=getmaxflow(e[i].y,min(e[i].flow,flow-f))){
    					f+=d;e[i].flow-=d;e[e[i].back].flow+=d;
    					if(f==flow) return f;
    				}
    			}
    		}
    		if(!f) level[x]=-1;
    		return f;
    	}
    	inline int dinic(){
    		int ans=0,d;
    		while(getlevel()){
    			while(d=getmaxflow(s,inf)) ans+=d;
    		}
    		return ans;
    	}
    }
    namespace zkww{
    	inline bool getdis(){
    		memset(vis,0,sizeof(vis));
    		memset(dis,10,sizeof(dis));
    		dis[t]=0;
    		deque<int>q;q.push_back(t);
    		while(!q.empty()){
    			int tn=q.front();q.pop_front();
    			for(int i=linkk[tn];i;i=e[i].next){
    				if(dis[tn]-e[i].w<dis[e[i].y]&&e[e[i].back].flow){
    					dis[e[i].y]=dis[tn]-e[i].w;
    					if(!vis[e[i].y]){
    						vis[e[i].y]=1;
    						if(!q.empty()&&dis[e[i].y]<dis[q.front()]) q.push_front(e[i].y);
    						else q.push_back(e[i].y);
    					}
    				}
    			}
    			vis[tn]=0;
    		}
    		return dis[s]<168430090;
    	}
    	inline int getcost(int x,int flow){
            int f=0,d;vis[x]=1;
    		if(x==t) return flow;
    		for(int i=linkk[x];i;i=e[i].next){
    			if(e[i].flow&&dis[e[i].y]==dis[x]-e[i].w&&!vis[e[i].y]){
    				if(d=getcost(e[i].y,min(flow-f,e[i].flow))){
    					f+=d;e[i].flow-=d;e[e[i].back].flow+=d;
    					ans+=e[i].w*d;
    					if(f==flow) return f;
    				}
    			}
    		}
    		return f;
    	}
    	inline void zkw(){
    		while(getdis()){
    			vis[t]=1;
    			while(vis[t]){
    				memset(vis,0,sizeof(vis));
    				getcost(s,inf);
    			}
    		}
    	}
    }
    void build(){
    	s=0;t=n;
    	insert(s,1,k,0);
    	for(int i=1;i<=m;i++){
    		insert(x[i],y[i],inf,c[i]);
    	}
    }
    int main(){
    	using namespace dinicc;
    	using namespace zkww;
    	n=read();m=read();k=read();s=1;t=n;
    	for(int i=1;i<=m;i++){
    		x[i]=read();y[i]=read();f[i]=read();c[i]=read();
    		insert(x[i],y[i],f[i],0);
    	}
    	ans=dinic();
    	cout<<ans<<' ';
    	build();ans=0;
    	zkw();
    	cout<<ans<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    iOS5.1下emoji表情显示方框的解决办法
    iPhone处理图片(UIImage扩展类) 自动适应frame大小方法
    10个必需的iOS开发工具和资源
    转一篇:iOSOpenDev环境搭建以及使用
    自定义UITabbarController引发的血案
    (转) iphone开发资源汇总
    分类分享一下,关于push推送的经验吧
    关于IPHONE的设计模式
    IOS自动化打包介绍
    带有可变参数表的简化的printf函数
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/9012332.html
Copyright © 2011-2022 走看看