Uvaoj 11248 Frequency Hopping(Dinic求最小割)
题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量
可以达到目的,那么输出possible option:接着输出每一条可以达到目的的边(按升序),再否则输出not possible
思路:先求一次最大流,如果流量至少为C,则直接输出possible,否则需要修改的弧一定在最小割里!
接着吧这些弧(最小割里的)的容量设为无穷大,然后在求最大流,看最大流的流量能否满足是C即可,如果满足了,那就把这一条边记录下来
分析:最大流的程序没有必要完全的执行完毕,知道当前的流量>=C那么就可以中止最大流的程序!
还有就是第一次的最大流程序如果没有找到>=C的最大流,那么此时的流量留着,下一次在最小割里扩容的时候,总是接着第一次Dinic的流量
继续寻找....
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 #define N 105 8 #define INF 2000000005 9 using namespace std; 10 11 struct EDGE{ 12 int u, v, nt, cap; 13 bool flag; 14 bool vis; 15 EDGE(){} 16 EDGE(int u, int v, int nt, int cap, bool flag):u(u), v(v), nt(nt), cap(cap), flag(flag){} 17 }; 18 19 struct node{ 20 int x, y; 21 node(){} 22 node(int x, int y) : x(x), y(y){} 23 }; 24 25 int pos[10005]; 26 27 node ans[10005]; 28 int preCost[20005]; 29 int vis[20005]; 30 int p[20005]; 31 int pcnt; 32 int cnt; 33 34 vector<EDGE>g; 35 int first[N]; 36 37 int d[N]; 38 int n, e, c; 39 40 void addEdge(int u, int v, int c){ 41 g.push_back(EDGE(u, v, first[u], c, true)); 42 first[u] = g.size() - 1; 43 g.push_back(EDGE(v, u, first[v], 0, false)); 44 first[v] = g.size() - 1; 45 } 46 47 bool bfs(){ 48 memset(d, 0, sizeof(d)); 49 d[1] = 1; 50 queue<int>q; 51 q.push(1); 52 while(!q.empty()){ 53 int u = q.front(); 54 q.pop(); 55 for(int i = first[u]; ~i; i = g[i].nt){ 56 int v = g[i].v; 57 if(!d[v] && g[i].cap > 0){ 58 d[v] = d[u] + 1; 59 q.push(v); 60 } 61 } 62 } 63 if(d[n] == 0) return false; 64 return true; 65 } 66 67 bool cmp(node a, node b){ 68 if(a.x == b.x) 69 return a.y < b.y; 70 return a.x < b.x; 71 } 72 73 int leave; 74 75 int dfs(int u, int totf){ 76 int flow = 0; 77 if(u ==n || totf==0) return totf; 78 for(int i = first[u]; ~i; i = g[i].nt){ 79 int v = g[i].v; 80 if(d[v] == d[u] + 1 && g[i].cap > 0){ 81 int ff = dfs(v, min(totf-flow, g[i].cap)); 82 if(ff > 0){ 83 if(!vis[i]){ 84 p[pcnt++]=i; 85 preCost[i] = g[i].cap; 86 vis[i] = 1; 87 } 88 g[i].cap -= ff; 89 90 if(!vis[i^1]){ 91 p[pcnt++]=i^1; 92 preCost[i^1] = g[i^1].cap; 93 vis[i^1] = 1; 94 } 95 g[i^1].cap += ff; 96 flow += ff; 97 98 if(flow >= leave){ 99 flow = leave; 100 return flow; 101 } 102 103 if(totf == flow) break; 104 } 105 else d[v] = -1; 106 } 107 } 108 return flow; 109 } 110 111 bool Dinic(){ 112 leave = c; 113 while(bfs()){ 114 leave -= dfs(1, INF); 115 if(leave == 0) break; 116 } 117 if(leave == 0) return true; 118 return false; 119 } 120 121 122 123 int main(){ 124 int cas = 0; 125 while(scanf("%d%d%d", &n, &e, &c)){ 126 if(!n) break; 127 memset(first, -1, sizeof(first)); 128 g.clear(); 129 cnt = 0; 130 while(e--){ 131 int x, y, z; 132 scanf("%d%d%d", &x, &y, &z); 133 addEdge(x, y, z); 134 } 135 printf("Case %d: ", ++cas);//这一块差点没有把我气死...居然有一个空格,没有看清楚啊...一直PE. 136 137 if(n==1){ 138 printf("possible\n"); 139 continue; 140 } 141 142 if(Dinic()) printf("possible\n"); 143 else{ 144 int len = g.size(); 145 for(int i=0; i<len; ++i) 146 if(g[i].cap == 0 && g[i].flag) 147 pos[cnt++] = i;//得到最小割 148 int cc = leave;//第一次Dinic之后,还剩下多少的流量需要流过 149 int ret = 0; 150 for(int i=0; i<cnt; ++i){ 151 c = cc;//新的需要流过的流量 152 pcnt = 0; 153 g[pos[i]].cap = INF; 154 memset(vis, 0, sizeof(vis)); 155 if(Dinic())//如果增广成功,那么这条最小割满足 156 ans[ret++] = node(g[pos[i]].u, g[pos[i]].v); 157 for(int j=0; j<pcnt; ++j) 158 g[p[j]].cap = preCost[p[j]];//将Dinic中所经过的边的值恢复成第一次Dinic之后的值! 159 g[pos[i]].cap = 0; 160 } 161 if( ret > 0 ){ 162 sort(ans, ans+ret, cmp); 163 printf("possible option:(%d,%d)", ans[0].x, ans[0].y); 164 for(int i=1; i<ret; ++i) 165 printf(",(%d,%d)", ans[i].x, ans[i].y); 166 printf("\n"); 167 } 168 else printf("not possible\n"); 169 } 170 } 171 return 0; 172 }
View Code
转载于:https://www.cnblogs.com/hujunzheng/p/4014923.html
Uvaoj 11248 Frequency Hopping(Dinic求最小割)相关推荐
- Sabotage UVA - 10480 (最小割+求最小割去掉的具体边+ISAP)
传送门 题意:给定n个点,m条带权无向边,源点s=1,汇点t=2.去掉一些边之后使s,t不连通,求去掉的这些边(而且还要满足去掉的边权和是所有答案中最小的--最小割). n<=50,m<= ...
- S-T平面图中利用最短路求最小割(BZOJ 1001)
BZOJ 1001: [BeiJing2006]狼抓兔子 最小割 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 现在小朋友们最喜欢 ...
- matlab求最小割,matlab實現圖割算法中的最大流最小割Max-flow/min-cut問題(一)
本篇主要介紹matlab實現Max-flow/min-cut的方法,介紹一種只實現了Max-flow/min-cut的工具箱Bk_matlab. 一:最大流最小割的由來 了解這個問題之前先說說這個問題 ...
- 图论 —— 网络流 —— 最小割 —— 最大权闭合子图
[概述] 给出一个有向图,每一个点都有一个权值,现在要选择一个权值和最大的子图,使得每个点的后继都在子图中,这个子图就称为最大权闭合子图. 如上图,能选的子图有:Ø.{1,2,3,4,5,6}.{3, ...
- Dinic求最大流/最小割
o(v^2*E) 建图时建一条流量为0的反向边,正向边每减去流量f,反向边增加流量f.对于无向图当做两条边. cap:每条边最大流量 建图后: 调用DINIC():用bfs()为每个节点进行层次编号, ...
- BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)
题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...
- 【BZOJ - 1001】狼抓兔子(无向图网络流,最小割,或平面图转对偶图求最短路SPFA)
题干: 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- BZOJ 2132 圈地计划(最小割)【BZOJ 修复工程】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2132 是 hydro 的 BZOJ ...
- hdu 3987(最小割的边数)
题意:给出一张有n个点的图,有的边又向,有的边无向,现在要你破坏一些路,使得从点0无法到达点n-1.破坏每条路都有一个代价.求在代价最小的前提下,最少需要破坏多少条道路.(就是说求在最小割的前提下,最 ...
最新文章
- Linux修改文件及文件夹权限
- fatal error C1900: Il mismatch between 'P1' version '20060201' and 'P2' version '20050411'
- Intel Idea导入eclipse下的web项目并部署到tomcat
- 17电大计算机网考模拟题,2017年电大 201717统考电大计算机应用基础网考试题.doc...
- 【Linux】一步一步学Linux——kill命令(124)
- Java EE 8 MVC:Ozark入门
- 《深入解析sas:数据处理、分析优化与商业应用》一3.5 SAS常用函数
- Magedu2_3 linux文件目录
- ThinkPad X220i 安装 Mac OSX
- 【推荐】互联网或技术多平台,一文多发小工具!
- Android 程序员计算器 开发记录-Git版本控制初步接触
- Python 模块:XlsxWriter 的使用
- 中国石油井架行业发展前景与投资盈利预测报告2022-2027
- zone在linux中的含义,linux-日常运维-firewalld的9个zone
- CEPH OSD_SCRUB_ERRORS 错误处理
- 电力设备事故演练仿真培训_电力事故VR培训_广州华锐互动
- Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding
- 某电子计算机有400个终端,(概率四习题.doc
- oracle费用类物料采购,ebs费用化物料设置
- GhostXP_SP2电脑公司特别版_v8.5_island完美版
热门文章
- geth 转账_eth客户端安装 geth使用 批量转账(一)
- DockerFile 入门到精通
- SpringBoot 整合 Spring Cloud Alibaba Nacos 连通性+负载均衡
- Flowable 数据库表结构 ACT_RU_JOB
- linux下后台启动springboot项目
- Trigger触发器_05
- SpringBoot入门到精通_第5篇 _SpringBoot Actuator监控
- 牛客网SQL篇刷题篇(3-10)
- markdown html vue,vue项目引入markdown
- C语言 指针数组和数组指针区别 - C语言零基础入门教程