题意:

给定一个有向网络,每条边均有一个容量。问是否存在一个从点1到点N,流量为C的流。如果不存在,是否可以恰好修改一条弧的容量,使得存在这样的流?

分析:

先跑一遍最大流,如果最大流大于等于C,则输possible。如果最大流小于C,则表明需要修改边的流量。很显然,需要修改的弧一定是满流的弧。但是如果直接暴力会超时,所以我们可以有两个优化。

1.第一次求完最大流以后,把每条弧的流量保存下来,每次修改完一条弧的容量以后,都从当前残量网络开始继续增广。

2.每次不需要增广到最大流,当流量大于等于C的时候就停止增广(不过不加这个优化好像也没事,反正我没加··)

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector> using namespace std;
const int maxn=+;
const int maxm=+;
const int INF=;
struct Dinic{
int head[maxn],Next[maxm],to[maxm],from[maxm],cap[maxm],flow[maxm];
int n,m,s,t,sz;
bool vis[maxn];
int d[maxn],cur[maxn];
void init(int n){
this->n=n;
sz=-;
memset(head,-,sizeof(head));
}
void add_edge(int a,int b,int c){
++sz;
to[sz]=b;Next[sz]=head[a];head[a]=sz;
cap[sz]=c;flow[sz]=,from[sz]=a;;
++sz;
to[sz]=a;Next[sz]=head[b];head[b]=sz;
cap[sz]=c;flow[sz]=c,from[sz]=b;
}
bool BFS(){
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)d[i]=INF;
queue<int>Q;
d[s]=,vis[s]=;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=head[u];i!=-;i=Next[i]){
int v=to[i];
if(cap[i]>flow[i]&&!vis[v]){
vis[v]=;
d[v]=d[u]+;
Q.push(v);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x==t||a==)return a;
int Flow=,f;
for(int& i=cur[x];i!=-;i=Next[i]){
int v=to[i];
if(d[v]==d[x]+&&(f=DFS(v,min(a,cap[i]-flow[i])))>){
Flow+=f;
flow[i]+=f;
flow[i^]-=f;
a-=f;
if(a==)break;
}
}
return Flow;
}
int Maxflow(int s,int t){
this->s=s;this->t=t;
int Flow=;
while(BFS()){
for(int i=;i<=n;i++)cur[i]=head[i];
Flow+=DFS(s,INF);
}
return Flow;
}
}dinic;
struct Edge{
int from,to;
bool operator <(const Edge& rhs)const{
return from<rhs.from||(from==rhs.from&&to<rhs.to);
}
};
vector<Edge>ans;
int kase,N,E,C;
int main(){
kase=;
while(scanf("%d%d%d",&N,&E,&C)!=EOF&&(N||E||C)){
++kase;
printf("Case %d: ",kase);
ans.clear();
dinic.init(N);
int u,v,c;
for(int i=;i<=E;i++){
scanf("%d%d%d",&u,&v,&c);
dinic.add_edge(u,v,c);
}
int Maxflow=dinic.Maxflow(,N);
if(Maxflow>=C){
printf("possible\n");
}else{
int FLOW[maxm];
for(int i=;i<=dinic.sz;i++){
FLOW[i]=dinic.flow[i];
}
int CAP,c=C-Maxflow;
for(int i=;i<=dinic.sz;i+=){
if(dinic.cap[i]==dinic.flow[i]){ for(int i=;i<=dinic.sz;i++)dinic.flow[i]=FLOW[i];
CAP=dinic.cap[i];
dinic.cap[i]=C;
dinic.cap[i^]=C;
Maxflow=dinic.Maxflow(,N);
if(Maxflow>=c){
ans.push_back((Edge){dinic.from[i],dinic.to[i]});
}
dinic.cap[i]=CAP;
dinic.cap[i^]=CAP;
for(int i=;i<=dinic.sz;i++)dinic.flow[i]=FLOW[i];
}
}
if(ans.size()==){
printf("not possible\n");
}else{
sort(ans.begin(),ans.end());
printf("possible option:");
for(int i=;i<ans.size();i++){
if(i!=)printf(",");
printf("(%d,%d)",ans[i].from,ans[i].to);
}
printf("\n");
}
}
}
return ;
}

【LA11248 训练指南】网络扩容【最大流】的更多相关文章

  1. BZOJ 1834: [ZJOI2010]network 网络扩容(最大流+最小费用最大流)

    第一问直接跑最大流.然后将所有边再加一次,费用为扩容费用,容量为k,再从一个超级源点连一条容量为k,费用为0的边到原源点,从原汇点连一条同样的边到超级汇点,然  后跑最小费用最大流就OK了. ---- ...

  2. 【BZOJ1834】[ZJOI2010]network 网络扩容 最大流+最小费用流

    [BZOJ1834][ZJOI2010]network 网络扩容 Description 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不 ...

  3. bzoj 1834: [ZJOI2010]network 网络扩容 -- 最大流+费用流

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Description 给定一张有向图,每条边都有一个容量C和一 ...

  4. [BZOJ1834][ZJOI2010]network 网络扩容 最大流+费用流

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec  Memory Limit: 64 MB Submit: 3330  Solved: 1739 [Subm ...

  5. BZOJ 1834 网络扩容 最大流+最小费用流

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1834 题目大意: 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是 ...

  6. [ZJOI2010][bzoj1834] 网络扩容 [费用流]

    题面 传送门 思路 第一问:无脑网络流跑一波 第二问: 先考虑一个贪心的结论:扩容出来的扩容流量一定要跑满 证明显然 因此我们可以把扩容费用可以换个角度思考,变成增加一点流量,花费W的费用 这样,我们 ...

  7. bzoj1834: [ZJOI2010]network 网络扩容 费用流

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

  8. BZOJ 1834 网络扩容(最大流+费用流)

    对于第一问,直接求最大流. 对于第二问,建源点s和汇点t,s连1容量为INF,费用为0的边,n连t容量为最大流+k,费用为0的边.这样就把最大流限制为最多增加k了. 限制需要求扩充的最小费用,原图的边 ...

  9. BZOJ-1834 网络扩容 最小费用最大流+最大流+乱搞

    1834: [ZJOI2010]network 网络扩容 Time Limit: 3 Sec Memory Limit: 64 MB Submit: 2269 Solved: 1136 [Submit ...

随机推荐

  1. select rows by values in a column from Dataframe

    df.loc[df['column_name'] == some_value] details in: http://stackoverflow.com/questions/17071871/sele ...

  2. js中将时间(如:2017-10-8 22:44:55)转化为时间搓,时间戳转为标准格式时间

    function split_time(time){//将当前时间转换成时间搓 例如2013-09-11 12:12:12 var arr=time.split(" "); var ...

  3. 【转】VC中MessageBox与AfxMessageBox用法与区别

    原文网址:http://blog.csdn.net/holybin/article/details/28403109 一.MessageBox()用法 1.函数原型 Messagebox函数在Win3 ...

  4. Qt学习之秒表的实现(StopWatch) (转)

    秒表对于我来说并不陌生,在之前自己学习单片机时,实现过秒表和数字钟:基本思路:开启单片机带的定时器,并设置它没10ms溢出一次,分别用三个变量hour,minute,secong记录秒表的时分秒,然后 ...

  5. MEF学习总结(1)---总体架构

    用了很久的MEF框架来做依赖注入,最近想把它的原理和机构总结一下,主要包括如下几个方面: 1. 总体架构 2. .Net Composition Primitive 3. Attribute Mode ...

  6. Python Socke

    回射 SERVER #!/usr/bin/python3 #_*_ coding:utf- _*_ import socket,os,time import socketserver import t ...

  7. Makefile编写 五 隐含规则

    隐含规则———— 在我们使用Makefile时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix下是[.o]文件,Windows下是[.obj] ...

  8. (转)Inno Setup入门(八)——有选择性的安装文件

    本文转载自:http://blog.csdn.net/yushanddddfenghailin/article/details/17250827 这主要使用[Components]段实现,一个演示的代 ...

  9. java------------break;

    总结: package com.mmm; public class Pnal { public static void main(String[] args) { int i = 0; while ( ...

  10. SpringMVC中注解控制器及数据绑定

    一.Spring2.5之前,我们都是通过实现Controller接口或其他实现来定义我们的处理器类. 二.Spring2.5引入注解式处理器支持,通过@Controller 和 @RequestMap ...