bzoj1834 网络扩容 网络流
好久没写题解了啊···
题目大意:
给你一幅n个点的网络,先求出其1到n的最大流,每条弧还会有个属性\(cost_i\),表示没扩容一个单位的费用,现在我们要求的就是扩容K个单位的最小费用
思路:
这是一道比较裸的网络流,第一问直接dinic就是了,重点就在于第二问。我们把第一问的残量网络继续利用,其中的每条弧的费用都是0,此时我们再在第\(i\)条弧的两端之间在建一条弧,弧的容量是\(INF\),费用就是\(cost_i\)。这样我们固然可以保证费用正确,可是我们保证不了扩容了K,我们就可以建一个超级源点,连向1号点,容量为K,费用为0。在这个网络中最大流一定是满流,也就是K啊,此时的最小费用就是我们所要求的。
具体实现:
这就很简单了,一遍\(dinic\),再一遍\(MCMF\)我们就可以了
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=10001,maxm=50001,inf=0x7f7f7f7f;
int n,m,k,tot,next[maxm<<1],beg[maxm<<1],head[maxn],flow[maxm<<1],fflow[maxm<<1],last[maxn],pre[maxn],fl[maxn],nxt[maxm<<1],to[maxm<<1],ccost[maxm<<1],cost[maxm<<1],d[maxn],dep[maxn];
bool vis[maxn];
void addedge(int x,int y,int z,int co,int type){
    nxt[++tot]=head[x];
    head[x]=tot;
    to[tot]=y;
    beg[tot]=x;
    flow[tot]=z;
    fflow[tot]=type?z:0;
    cost[tot]=type?co:0;
    ccost[tot]=co;
}
bool bfs(){
    memset(dep,0,sizeof(dep));
    queue<int> q;
    q.push(1);
    dep[1]=1;
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=nxt[i]){
            int u=flow[i],v=to[i];
            if(u>0 and !dep[v]){
                dep[v]=dep[x]+1;
                q.push(v);
            }
        }
    }
    return dep[n];
}
int dfs(int x,int mini){
    if(x==n)return mini;
    for(int i=head[x];i;i=nxt[i]){
        int u=flow[i],v=to[i];
        if(u>0 and dep[v]==dep[x]+1){
            int dd=dfs(v,min(mini,u));
            if(dd>0){
                flow[i]-=dd;
                flow[i^1]+=dd;
                return dd;
            }
        }
    }
    return 0;
}
int dinic(){
    int ret=0;
    while(bfs()){
        int tmp=dfs(1,inf);
        while(tmp){
            ret+=tmp;
            tmp=dfs(1,inf);
        }
    }
    return ret;
}
bool spfa() {
    memset(d,0x7f,sizeof(d));
    memset(fl,0x7f,sizeof(fl));
    memset(vis,0,sizeof(vis));
    queue<int> q;
    q.push(n+1);
    vis[n+1]=1;
    d[n+1]=0;
    pre[n]=-1;
    while(!q.empty()) {
        int now=q.front();
        q.pop();
        for(int i=head[now];i;i=nxt[i]){
            int v=to[i];
            if(fflow[i]>0 and d[v]>d[now]+cost[i]){
                d[v]=d[now]+cost[i];
                pre[v]=now;
                last[v]=i;
                fl[v]=min(fl[now],fflow[i]);
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
        vis[now]=0;
    }
    return pre[n]!=-1;
}
int mcmf(){
    int ret=0;
    while (spfa()){
        int now=n;ret+=fl[n]*d[n];
        while (now!=n+1){
            fflow[last[now]]-=fl[n];
            fflow[last[now]^1]+=fl[n];
            now=pre[now];
        }
    }
    return ret;
}
void rebuild(){
	int cnt=tot;
	for(int i=2;i<=cnt;i+=2){
		fflow[i]=flow[i];
		fflow[i+1]=flow[i+1];
		addedge(beg[i],to[i],inf,ccost[i],1);
		addedge(to[i],beg[i],0,-ccost[i],1);
	}
}
int main(){
    scanf("%d%d%d",&n,&m,&k);
    addedge(n+1,1,k,0,1);
    for(int i=1;i<=m;i++){
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        addedge(a,b,c,d,0);
        addedge(b,a,0,-d,0);
    }
    int ans1=dinic();
    rebuild();
    int ans2=mcmf();
    printf("%d %d\n",ans1,ans2);
    return 0;
}
												
											bzoj1834 网络扩容 网络流的更多相关文章
- BZOJ-1834  网络扩容    最小费用最大流+最大流+乱搞
		
1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 2269 Solved: 1136 [Submit ...
 - [ZJOI2010][bzoj1834] 网络扩容 [费用流]
		
题面 传送门 思路 第一问:无脑网络流跑一波 第二问: 先考虑一个贪心的结论:扩容出来的扩容流量一定要跑满 证明显然 因此我们可以把扩容费用可以换个角度思考,变成增加一点流量,花费W的费用 这样,我们 ...
 - bzoj1834 网络扩容
		
Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的 ...
 - 洛谷$P2604\ [ZJOI2010]$网络扩容 网络流
		
正解:网络流 解题报告: 传送门$QwQ$ 昂第一问跑个最大流就成不说$QwQ$ 然后第二问,首先原来剩下的边就成了费用为0的边?然后原来的所有边连接的两点都给加上流量为$inf$费用为$w$的边,保 ...
 - 【BZOJ1834】网络扩容(最大流,费用流)
		
[BZOJ1834]网络扩容(最大流,费用流) 题面 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下 ...
 - 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流
		
[BZOJ1834][ZJOI2010]network 网络扩容 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不 ...
 - 【bzoj1834】[ZJOI2010]network 网络扩容
		
1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 2701 Solved: 1368[Submit ...
 - [BZOJ1834][ZJOI2010]network 网络扩容  最大流+费用流
		
1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 3330 Solved: 1739 [Subm ...
 - bzoj1834: [ZJOI2010]network 网络扩容
		
努力看了很久样例一直过不了...然后各种输出中间过程啊巴拉巴拉弄了1h,没办法了...然后突然想到啊原来的边可以用啊为什么不用...于是A了...感人肺腑 #include<cstdio> ...
 
随机推荐
- [转]MySQL游标的使用
			
转自:http://www.cnblogs.com/sk-net/archive/2011/09/07/2170224.html 以下的文章主要介绍的是MySQL游标的使用笔记,其可以用在存储过程的S ...
 - NSoup获取网页源代码
			
NSoup是JSoup的Net移植版本.使用方法基本一致. 如果项目涉及HTML的处理,强烈推荐NSoup,毕竟字符串截断太苦逼了. 下载地址:http://nsoup.codeplex.com/ # ...
 - 关于表单清空的细节(reset函数或者class="reset"属性)
			
在需要清空的表单的情况下, 如果是在页面中 那么就添加属性 class="reset" 也即是 <button class="reset" value= ...
 - TCP/UDP套接字 java socket编程实例
			
网络协议七层结构: 什么是Socket? socket(套接字)是两个程序之间通过双向信道进行数据交换的端,可以理解为接口.使用socket编程也称为网络编程,socket只是接口并不是网络通信协议. ...
 - VMware虚拟机下载与安装
			
VMware下载与安装 一.虚拟机的下载 1.进入VMware官网,点击左侧导航栏中的下载,再点击图中标记的Workstation Pro,如下图所示. 2.根据操作系统选择合适的产品,在这里以Win ...
 - PHP常量和数据类型考察点
			
PHP 常量 常量是单个值的标识符(名称).在脚本中无法改变该值. 有效的常量名以字符或下划线开头(常量名称前面没有 $ 符号). 注释:与变量不同,常量贯穿整个脚本是自动全局的. PHP常量的两种定 ...
 - iTOP-4412开发板网盘资料介绍
			
iTOP-4412开发板网盘视频资料内容如下: 01-烧写.编译以及基础知识视频 02-嵌入式Linux 视频 03-iTOP-4412 开发板硬件设计指导视频 04-Android 应用程序视频 0 ...
 - CSS3 自动旋转
			
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
 - 去除inline-block间距
			
去除inline-block间距 通过display:inline-block设置元素为水平时,相邻元素之间会有几px的间距: html: <ul class="list"& ...
 - 比较 String,StringBuffer,StringBuilder
			
1)三者在执行速度方面的比较:StringBuilder > StringBuffer > String 2)String <(StringBuffer,StringBuild ...