题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量
可以达到目的,那么输出possible option:接着输出每一条可以达到目的的边(按升序),再否则输出not possible
思路:先求一次最大流,如果流量至少为C,则直接输出possible,否则需要修改的弧一定在最小割里!
接着吧这些弧(最小割里的)的容量设为无穷大,然后在求最大流,看最大流的流量能否满足是C即可,如果满足了,那就把这一条边记录下来

分析:最大流的程序没有必要完全的执行完毕,知道当前的流量>=C那么就可以中止最大流的程序!
还有就是第一次的最大流程序如果没有找到>=C的最大流,那么此时的流量留着,下一次在最小割里扩容的时候,总是接着第一次Dinic的流量
继续寻找....

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#define N 105
#define INF 2000000005
using namespace std; struct EDGE{
int u, v, nt, cap;
bool flag;
bool vis;
EDGE(){}
EDGE(int u, int v, int nt, int cap, bool flag):u(u), v(v), nt(nt), cap(cap), flag(flag){}
}; struct node{
int x, y;
node(){}
node(int x, int y) : x(x), y(y){}
}; int pos[]; node ans[];
int preCost[];
int vis[];
int p[];
int pcnt;
int cnt; vector<EDGE>g;
int first[N]; int d[N];
int n, e, c; void addEdge(int u, int v, int c){
g.push_back(EDGE(u, v, first[u], c, true));
first[u] = g.size() - ;
g.push_back(EDGE(v, u, first[v], , false));
first[v] = g.size() - ;
} bool bfs(){
memset(d, , sizeof(d));
d[] = ;
queue<int>q;
q.push();
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = first[u]; ~i; i = g[i].nt){
int v = g[i].v;
if(!d[v] && g[i].cap > ){
d[v] = d[u] + ;
q.push(v);
}
}
}
if(d[n] == ) return false;
return true;
} bool cmp(node a, node b){
if(a.x == b.x)
return a.y < b.y;
return a.x < b.x;
} int leave; int dfs(int u, int totf){
int flow = ;
if(u ==n || totf==) return totf;
for(int i = first[u]; ~i; i = g[i].nt){
int v = g[i].v;
if(d[v] == d[u] + && g[i].cap > ){
int ff = dfs(v, min(totf-flow, g[i].cap));
if(ff > ){
if(!vis[i]){
p[pcnt++]=i;
preCost[i] = g[i].cap;
vis[i] = ;
}
g[i].cap -= ff; if(!vis[i^]){
p[pcnt++]=i^;
preCost[i^] = g[i^].cap;
vis[i^] = ;
}
g[i^].cap += ff;
flow += ff; if(flow >= leave){
flow = leave;
return flow;
} if(totf == flow) break;
}
else d[v] = -;
}
}
return flow;
} bool Dinic(){
leave = c;
while(bfs()){
leave -= dfs(, INF);
if(leave == ) break;
}
if(leave == ) return true;
return false;
} int main(){
int cas = ;
while(scanf("%d%d%d", &n, &e, &c)){
if(!n) break;
memset(first, -, sizeof(first));
g.clear();
cnt = ;
while(e--){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
addEdge(x, y, z);
}
printf("Case %d: ", ++cas);//这一块差点没有把我气死...居然有一个空格,没有看清楚啊...一直PE. if(n==){
printf("possible\n");
continue;
} if(Dinic()) printf("possible\n");
else{
int len = g.size();
for(int i=; i<len; ++i)
if(g[i].cap == && g[i].flag)
pos[cnt++] = i;//得到最小割
int cc = leave;//第一次Dinic之后,还剩下多少的流量需要流过
int ret = ;
for(int i=; i<cnt; ++i){
c = cc;//新的需要流过的流量
pcnt = ;
g[pos[i]].cap = INF;
memset(vis, , sizeof(vis));
if(Dinic())//如果增广成功,那么这条最小割满足
ans[ret++] = node(g[pos[i]].u, g[pos[i]].v);
for(int j=; j<pcnt; ++j)
g[p[j]].cap = preCost[p[j]];//将Dinic中所经过的边的值恢复成第一次Dinic之后的值!
g[pos[i]].cap = ;
}
if( ret > ){
sort(ans, ans+ret, cmp);
printf("possible option:(%d,%d)", ans[].x, ans[].y);
for(int i=; i<ret; ++i)
printf(",(%d,%d)", ans[i].x, ans[i].y);
printf("\n");
}
else printf("not possible\n");
}
}
return ;
}

Uvaoj 11248 Frequency Hopping(Dinic求最小割)的更多相关文章

  1. uva 11248 Frequency Hopping (最大流)

    uva 11248 Frequency Hopping 题目大意:给定一个有向网络,每条边均有一个容量. 问是否存在一个从点1到点N.流量为C的流.假设不存在,能否够恰好改动一条弧的容量,使得存在这种 ...

  2. UVA 11248 - Frequency Hopping(网络流量)

    UVA 11248 - Frequency Hopping 题目链接 题意:给定一个网络,如今须要从1到N运输流量C,问是否可能,假设可能输出可能,假设不可能,再问能否通过扩大一条边的容量使得可能,假 ...

  3. [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割

    题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...

  4. poj 3469 Dual Core CPU【求最小割容量】

    Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 21453   Accepted: 9297 ...

  5. BZOJ_1001_狼抓兔子_(平面图求最小割+对偶图求最短路)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1001 1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec   ...

  6. HDU - 3035 War(对偶图求最小割+最短路)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3035 题意 给个图,求把s和t分开的最小割. 分析 实际顶点和边非常多,不能用最大流来求解.这道题要用 ...

  7. sw算法求最小割学习

    http://  blog.sina.com.cn/s/blog_700906660100v7vb.html 转载:http://www.cnblogs.com/ylfdrib/archive/201 ...

  8. UVA 11248 Frequency Hopping

    Frequency Hopping Time Limit: 10000ms Memory Limit: 131072KB This problem will be judged on UVA. Ori ...

  9. BZOJ 1001: [BeiJing2006]狼抓兔子(s-t平面图+最短路求最小割)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1001 题意: 思路:这道题目是最小割题目,但是吧你直接套用Dinic是会超时的. 这里有种很奇妙的做 ...

随机推荐

  1. Linux 常用命令小结

    学习脚本几天了,总结下linux debian下脚本常用命令. Linux    1.添加删除账户 useradd / userdel    2.修改"张三"密码 passwd 张 ...

  2. linux下IPTABLES配置详解(转)

    如果你的IPTABLES基础知识还不了解,建议先去看看. 开始配置 我们来配置一个filter表的防火墙. (1)查看本机关于IPTABLES的设置情况 [root@tp ~]# iptables - ...

  3. .NET中的流

    当应用程序需要和磁盘上的文件打交道的时候,就有了流的概念.流就像架设在应用程序所在内存和磁盘之间的一个管道. 大致思路 → 建立管道 //FileMode.Open打开现有文件,另外还有FileMod ...

  4. Linux Futex的设计与实现(转)

    引子在编译2.6内核的时候,你会在编译选项中看到[*] Enable futex support这一项,上网查,有的资料会告诉你"不选这个内核不一定能正确的运行使用glibc的程序" ...

  5. Maven Learning - Direct Dependencies & Transitive Dependencies

    Dependencies declared in your project's pom.xml file often have their own dependencies. The main dep ...

  6. Oracle Essbase入门系列(三)

    数据库计算 Essbase中单元格的数据可以是外部输入或计算而得,单元格因而分为输入单元格和计算单元格.计算单元格的计算方法可以通过大纲中维度成员的合并计算符和公式脚本定义,此称为大纲计算定义. 例1 ...

  7. quick -- 创建精灵和动作

    local imgBg = display.newSprite("666666.jpg") :pos(display.cx, display.cy) :addTo(self) , ...

  8. 微信公众平台开发视频教程-03-获取Access Token和获取微信服务器IP,添加微信菜单

    1 获取access token 此token是以后每次调用微信接口都会带上的票据,token是公众号全局唯一票据,在调用其他接口之前都需要先得到token,taoken长度至少512个字符,通常用s ...

  9. C# 个人常用代码积累

    /// <summary> /// TextBox限制只能输入十六进制,且只能输入6个 /// </summary> /// <param name="send ...

  10. [转] js == 与 === 的区别

    1.对于string,number等基础类型,==和===是有区别的 1)不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等 2)同类型比较,直接进 ...