题意:

给定一个有向网络,每条边均有一个容量。问是否存在一个从点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. spring--集合注入(常规方法)

    数据,list,set,map,Properties 集合注入 package Spring_collections; /** * Created by luozhitao on 2017/8/11. ...

  2. sysbench 1.0.9 mysql 压测工具安装使用

    备注:    安装比较简单,可以使用源码或者使用yum 进行安装,本次测试使用yum    注意1.0 之后版本与老版本改动比较大,好多地方都有修改,本次测试使用    的mysql 使用docker ...

  3. docker swarm mode routing mesh 使用

    Docker Engine swarm mode makes it easy to publish ports for services to make them available to resou ...

  4. MATLAB自带工具箱实现PCA降维代码

    PCA基本流程: 1.训练集矩阵算协方差矩阵A; 2.算协方差矩阵特征值与特征向量; 3.按特征值的大小排列特征矩阵,得B,对应的特征值(按从大到小排列)组成向量a; 4.A*B得到去关联的新矩阵C, ...

  5. Ubuntu 破解密码及用户管理

    Ubuntu 破解密码及用户管理 ubuntu 16.04 破解密码 useradd 实现以下要求 1.ubuntu16.04破解密码 2.创建下面的用户.组和组成员关系 名字为xipudata 的组 ...

  6. [模板]LCA的倍增求法解析

    题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...

  7. css 字体英文对照

    宋体: SimSun 黑体: SimHei 华文细黑: STHeiti Light [STXihei] 华文黑体: STHeiti 微软雅黑: Microsoft YaHei 微软正黑体: Micro ...

  8. python 冒泡排序,二分法

    a = 0 lst = [13,5,1,7,2,6,4,5,6] while a < len(lst): # 控制次数 for i in range(len(lst)-1): if lst[i] ...

  9. 【转】活用软件测试工具之Jmeter活用

    软件测试工具不光能测试用,拿Jmeter来说,使用它可以进行web性能测试. 简单说一下大概使用: 如果要测试某个网页内的功能,首先要录制Jmeter脚本,脚本的录制与运行过程,也就是打开网页,执行被 ...

  10. java代码-------Runnable的用法

    总结:主要是实现Runnable接口就必须重写run()方法,然后需要创建Thread类的对象,再调用start()方法 package com.s.x; public class testRunna ...