博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Uvaoj 11248 Frequency Hopping(Dinic求最小割)
阅读量:6073 次
发布时间:2019-06-20

本文共 3213 字,大约阅读时间需要 10 分钟。

题意:1到n节点(节点之间有一定的容量),需要流过C的流量,问是否可以?如果可以输出possible, 否则如果可以扩大任意一条边的容量

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

分析:最大流的程序没有必要完全的执行完毕,知道当前的流量>=C那么就可以中止最大流的程序!

还有就是第一次的最大流程序如果没有找到>=C的最大流,那么此时的流量留着,下一次在最小割里扩容的时候,总是接着第一次Dinic的流量
继续寻找....

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
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
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
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
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
本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/4014923.html,如需转载请自行联系原作者
你可能感兴趣的文章
Java注册登陆学习笔记
查看>>
网站日志分析
查看>>
linux中init.d文件夹的说明
查看>>
【转】关于FILE **file
查看>>
spring boot DAO之Hibernate
查看>>
logstash初体验
查看>>
Python之基础篇(二)
查看>>
备用:三大连接池的参数说明(转)
查看>>
PHP学习笔记——入门篇(1)——语法&变量
查看>>
>xx.hbm.xml的一些简单配置
查看>>
scp和rsync的实际应用
查看>>
10.this关键字
查看>>
数据发送qstring问题
查看>>
回顾cocos2dx 开发(象棋)
查看>>
[Java] 异常处理
查看>>
Git中撤销提交
查看>>
工作与生活之平衡(3)远离开车带给我们的压力
查看>>
在CentOS 6.5 上 使用redhat RDO packstack安装 openstack icehouse
查看>>
Python基本语法
查看>>
常用服务协议端口
查看>>