• 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
    ");
    139             continue;
    140         }
    141 
    142         if(Dinic())  printf("possible
    ");
    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("
    ");
    167             }
    168             else printf("not possible
    ");
    169         }
    170     }    
    171     return 0;
    172 }
    View Code
  • 相关阅读:
    CSUST 8.4 早训
    CSUST 8.5 早训
    hdu1542 Atlantis 线段树--扫描线求面积并
    hdu1540 Tunnel Warfare 线段树/树状数组
    hdu1535 Invitation Cards 最短路
    hdu1358 Period KMP
    SQL Server 向数据库中创建表并添加数据
    初次实践数据库--SQL Server2016
    hdu1301 Jungle Roads 最小生成树
    hdu1281 棋盘游戏 二分图最大匹配
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/4014923.html
Copyright © 2020-2023  润新知