P2604 [ZJOI2010]网络扩容

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

说明

30%的数据中,N<=100

100%的数据中,N<=1000,M<=5000,K<=10


k这么小,开始以为是分层图搞事呢。

第一问裸的最大流。

第二问我们对初始的每条边新建一条费用边,容量为inf,表示随便用,单位费用就连初始费用,表示要花钱。

保证增加的流量为k,我们搞一个超级源点容量为k连原源点1。

在跑完最大流之后的残余网络上跑最小费用最大流。

之前对最大流求法中的反悔理解的不深刻,在写这个题的时候一直觉得直接跑残量网络失去了对原来最大流的反悔机会。但实际上,基于路径交换的反悔原理,直接跑残量网络是没问题的。

代码里面偷了懒,万一有免费的边就错了


Code:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=1010;
const int M=10010;
const int inf=0x3f3f3f3f;
int head[N],edge[M<<1],cost[M<<1],to[M<<1],Next[M<<1],cnt=1;
void add(int u,int v,int w,int c)
{
edge[++cnt]=w;cost[cnt]=c;Next[cnt]=head[u];to[cnt]=v;head[u]=cnt;
edge[++cnt]=0;cost[cnt]=-c;Next[cnt]=head[v];to[cnt]=u;head[v]=cnt;
}
int maxflow,n,m,k;
int dep[N];
bool bfs()
{
memset(dep,0,sizeof(dep));
dep[1]=1;
queue <int > q;
q.push(1);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=Next[i])
{
int v=to[i];
if(!cost[i]&&!dep[v]&&edge[i])
{
dep[v]=dep[u]+1;
if(v==n) return 1;
q.push(v);
}
}
}
return 0;
}
int dfs(int now,int flow)
{
if(now==n) return flow;
int rest=flow,k;
for(int i=head[now];i&&rest;i=Next[i])
{
int v=to[i];
if(!cost[i]&&edge[i]&&dep[v]==dep[now]+1)
{
k=dfs(v,min(rest,edge[i]));
if(!k) dep[v]=0;
rest-=k;
edge[i]-=k;
edge[i^1]+=k;
}
}
return flow-rest;
}
void Dinic()
{
int flow=0;
while(bfs())
while(flow=dfs(1,inf)) maxflow+=flow;
printf("%d ",maxflow);
}
int pre[N],used[N],dis[N];
int spfa()
{
queue <int > q;
q.push(0);
memset(dis,0x3f,sizeof(dis));
dis[0]=0;
while(!q.empty())
{
int u=q.front();
used[u]=0;
q.pop();
for(int i=head[u];i;i=Next[i])
{
int v=to[i];
if(edge[i]&&dis[v]>dis[u]+cost[i])
{
dis[v]=dis[u]+cost[i];
pre[v]=i;
if(!used[v])
used[v]=1,q.push(v);
}
}
}
return dis[n]!=inf;
}
void costflow()
{
int ans=0;
while(spfa())
{
int mi=inf;
for(int now=n;now;now=to[pre[now]^1])
mi=min(edge[pre[now]],mi);
ans+=dis[n]*mi;
for(int now=n;now;now=to[pre[now]^1])
edge[pre[now]]-=mi,edge[pre[now]^1]+=mi;
}
printf("%d\n",ans);
}
void init()
{
scanf("%d%d%d",&n,&m,&k);
int u,v,w,c;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&u,&v,&w,&c);
add(u,v,w,0),add(u,v,inf,c);
}
}
void work()
{
Dinic();
add(0,1,k,0);
costflow();
}
int main()
{
init();
work();
return 0;
}

2018.7.14

洛谷 P2604 [ZJOI2010]网络扩容 解题报告的更多相关文章

  1. 洛谷$P2604\ [ZJOI2010]$网络扩容 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 昂第一问跑个最大流就成不说$QwQ$ 然后第二问,首先原来剩下的边就成了费用为0的边?然后原来的所有边连接的两点都给加上流量为$inf$费用为$w$的边,保 ...

  2. [洛谷P2604][ZJOI2010]网络扩容

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

  3. 洛谷 P2604 [ZJOI2010]网络扩容

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

  4. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  5. 洛谷 P3171 [CQOI2015]网络吞吐量 解题报告

    P3171 [CQOI2015]网络吞吐量 题目描述 路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点.网络中实现路由转发的硬件设备称为路由器.为了使数据包最 ...

  6. 【题解】Luogu P2604 [ZJOI2010]网络扩容

    原题传送门:P2604 [ZJOI2010]网络扩容 这题可以说是板题 给你一个图,先让你求最大流 再告诉你,每条边可以花费一些代价,使得流量加一 问至少花费多少代价才能使最大流达到k 解法十分简单 ...

  7. 洛谷_Cx的故事_解题报告_第四题70

    1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h>   struct node {     long x,y,c; ...

  8. 洛谷 P2317 [HNOI2005]星际贸易 解题报告

    P2317 [HNOI2005]星际贸易 题目描述 输入输出格式 输入格式: 输出格式: 如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y.X表示贸易额,Y表示净利润并且两 ...

  9. 洛谷 P3802 小魔女帕琪 解题报告

    P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...

随机推荐

  1. 【C#利用后台动态加载数据】Winform“防界面卡死”【BackgroundWorker】类

    using System.ComponentModel 直接使用EgProgressBar方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  2. stl源码分析之priority queue

    前面两篇介绍了gcc4.8的vector和list的源码实现,这是stl最常用了两种序列式容器.除了容器之外,stl还提供了一种借助容器实现特殊操作的组件,谓之适配器,比如stack,queue,pr ...

  3. 180725-InfluxDB-v1.6.0安装和简单使用小结

    InfluxDB安装和简单使用小结 InfluxDB是一个时序性数据库,因为工作需求,安装后使用测试下是否支持大数据下的业务场景 说明: 安装最新版本 v1.6.0 集群版本要收费,单机版本免费 内部 ...

  4. realstudio 粒子特效问题总结

    ParticleEmitter._inner_material.flags.depth_write = true;ParticleEmitter._inner_material.flags.depth ...

  5. 【python 3.6】使用itertools.product进行排列组合

    #python 3.6 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'BH8ANK' import itertools colo ...

  6. Cuteftp连接虚拟机Centos7

    使用Centos7虚拟机时,想要从主机传一些文件到虚拟机,需要使用FTP传输,在主机上装上的CuteFTP的软件,对虚拟机进行配置. 1,首先,要保证虚拟机能够上网 一般装好虚拟机后,只要主机连了网, ...

  7. Numpy入门笔记第二天

    # 数组的组合 import numpy as np arr1 = np.arange(5) arr2 = np.arange(3) print arr1 print arr2 [0 1 2 3 4] ...

  8. Dubbo背景和简介

    转载出处 Dubbo开始于电商系统,因此在这里先从电商系统的演变讲起. 单一应用框架(ORM) 当网站流量很小时,只需一个应用,将所有功能如下单支付等都部署在一起,以减少部署节点和成本. 缺点:单一的 ...

  9. nginx响应client的处理机制

    nginx与apache的不同响应机制——epoll nginx可以处理上百万级别的并发请求就是源至于异步非阻塞的处理机制,异步非阻塞核心即是epoll nginx内部反向代理

  10. ORA-01747

    java.sql.SQLException: ORA-01747: user.table.column, table.column 或列说明 语法中多了逗号 或者字段使用关键字