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 }
复制代码









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/4014923.html,如需转载请自行联系原作者
目录
相关文章
|
C++
hackerrank challenges median
只能说这题我想多了,使用普通的插入排序完全可以解决这道题,在查找的时候用二分加快查找速度。 正确解题报告 这道题的关键在于,不能用int,因为两个int相加可能会越界!因为这个WA了好多遍。所以改用long long。 对double,使用math.h中的函数ceil(double)可以取整,根据ceil(v) == v的结果可以判断v是否是整数。
51 0
|
机器学习/深度学习 人工智能 自然语言处理
Term Frequency-Inverse Document Frequency
TF-IDF算法全称是&quot;Term Frequency-Inverse Document Frequency&quot;,可译为&quot;术语频率-文档逆向频率&quot;。
119 4
|
机器学习/深度学习 自然语言处理 算法
词频-逆文档频率(Term Frequency-Inverse Document Frequency,
词频-逆文档频率(Term Frequency-Inverse Document Frequency,简称 TF-IDF)是一种统计方法,用以评估一个词对于一个文本或一组文本的重要性。
521 3
paraforme支持speech_noise_threshold吗?
请问:speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch 这个模型支持设置 speech_noise_threshold 这个参数吗 ? vad 本身是支持的,但对这个集成的模型好像不起作用? 如果支持,应该如何正确地设置呢 ? 如果不支持,那该模型有没有什么方法可以过滤掉背景噪声? 经常会有背景噪声被识别出文字
59 0
|
机器学习/深度学习 数据挖掘 Python
使用Python实现Hull Moving Average (HMA)
赫尔移动平均线(Hull Moving Average,简称HMA)是一种技术指标,于2005年由Alan Hull开发。它是一种移动平均线,利用加权计算来减少滞后并提高准确性。
408 0
|
机器学习/深度学习 存储 算法
YOLOv5的Tricks | 【Trick7】指数移动平均(Exponential Moving Average,EMA)
这篇博客主要用于整理网上对EMA(指数移动平均)的介绍,在yolov5代码中也使用了这个技巧,现对其进行归纳。
1776 1
YOLOv5的Tricks | 【Trick7】指数移动平均(Exponential Moving Average,EMA)
【1096】Consecutive Factors (20 分)
【1096】Consecutive Factors (20 分) 【1096】Consecutive Factors (20 分)
124 0
Time range (447392) for take &#39;Take 001&#39; is larger than maximum allowed(100000).
http://www.cnblogs.com/lopezycj/archive/2012/05/16/unity3d_tuchao.html   https://forum.unity3d.com/threads/time-range-447406-for-translation-curve-s-on-node-bone001-on-take-take-001-what-the.
|
SQL Shell Perl
[20170604]12c Top Frequency histogram 2
[20170604]12c Top Frequency histogram补充.txt 1.环境: SCOTT@test01p> @ ver1 PORT_STRING                    VERSION        BANNER       ...
1010 0