• UVa 1440:Inspection(带下界的最小流)***


    https://vjudge.net/problem/UVA-1440

    题意:给出一个图,要求每条边都必须至少走一次,问最少需要一笔画多少次。

    思路:看了好久才勉强看懂模板。良心推荐:学习地址

    看完这个大概就能懂了。

    那条T->S的边的反向边的流量就是可行流的流量。
    最小流就是去掉新的源点和新的汇点(保证必要弧)和T->S边后,从T往S跑最大流(尽量退流),最小流的答案就是原来T->S的反向边流量 - 第二次最大流的流量。
    最大流就是去掉新的源点和新的汇点之后,再跑一遍最大流得到的就是答案。

    最小流这里后面看别人的发现别人是先跑一遍(SS->ST)最大流,然后再连<T,S>边,再跑一遍(SS->ST)最大流。然而论文里面是先连<T,S>边,跑一遍(SS->ST)最大流,然后删掉<T,S>边和所有与SS、ST相连的边,跑一遍(T->S)的最大流。

    看了N久还是不能完全理解。

    记得多组数组!!!WA了一晚上。

    写法一:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define N 210
      4 #define INF 0x3f3f3f3f
      5 struct Edge {
      6     int u, v, nxt, cap;
      7 } edge[N*N];
      8 int head[N], tot, dis[N], cur[N], pre[N], gap[N], in[N], out[N], S, T, SS, ST;
      9 
     10 void Add(int u, int v, int cap) {
     11     edge[tot].u = u, edge[tot].v = v, edge[tot].nxt = head[u], edge[tot].cap = cap, head[u] = tot++;
     12     edge[tot].u = v, edge[tot].v = u, edge[tot].nxt = head[v], edge[tot].cap = 0, head[v] = tot++;
     13 }
     14 
     15 int BFS(int T) {
     16     memset(dis, INF, sizeof(dis));
     17     memset(gap, 0, sizeof(gap));
     18     memcpy(cur, head, sizeof(cur));
     19     dis[T] = 0, gap[0]++;
     20     queue<int> que; que.push(T);
     21     while(!que.empty()) {
     22         int u = que.front(); que.pop();
     23         for(int i = head[u]; ~i; i = edge[i].nxt) {
     24             int v = edge[i].v;
     25             if(dis[v] == INF) {
     26                 dis[v] = dis[u] + 1;
     27                 gap[dis[v]]++;
     28                 que.push(v);
     29             }
     30         }
     31     }
     32 }
     33 
     34 int ISAP(int S, int T, int n) {
     35     BFS(T);
     36     int u = pre[S] = S, i, index, flow, ans = 0;
     37     while(dis[S] < n) {
     38         if(u == T) {
     39             flow = INF;
     40             for(i = S; i != T; i = edge[cur[i]].v)
     41                 if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
     42             for(i = S; i != T; i = edge[cur[i]].v)
     43                 edge[cur[i]].cap -= flow, edge[cur[i]^1].cap += flow;
     44             ans += flow, u = index;
     45         }
     46         for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap && dis[edge[i].v] + 1 == dis[u]) break;
     47         if(~i) {
     48             cur[u] = i; pre[edge[i].v] = u; u = edge[i].v;
     49         } else {
     50             if(--gap[dis[u]] == 0) break;
     51             int md = n;
     52             for(int i = head[u]; ~i; i = edge[i].nxt)
     53                 if(edge[i].cap && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
     54             gap[dis[u] = md + 1]++;
     55             u = pre[u];
     56         }
     57     }
     58     return ans;
     59 }
     60 
     61 void Delete() {
     62     for(int i = head[SS]; ~i; i = edge[i].nxt) edge[i].cap = edge[i^1].cap = 0;
     63     for(int i = head[ST]; ~i; i = edge[i].nxt) edge[i].cap = edge[i^1].cap = 0;
     64     edge[tot-1].cap = edge[(tot-1)^1].cap = 0;
     65 }
     66 
     67 void Update(int n) {
     68     for(int u = 1; u <= n; u++) {
     69         for(int i = head[u]; ~i; i = edge[i].nxt) {
     70             if(edge[i].v == S || edge[i].v == T || (i & 1)) continue;
     71             edge[i^1].cap++;
     72         }
     73     }
     74 }
     75 
     76 void Dfs(int u) {
     77     for(int i = head[u]; ~i; i = edge[i].nxt) {
     78         int v = edge[i].v;
     79         if(i & 1 || !edge[i^1].cap || v == S || v == T || v == SS || v == ST) continue;
     80         edge[i^1].cap--;
     81         printf(" %d", v);
     82         Dfs(v);
     83         break;
     84     }
     85 }
     86 
     87 int main() {
     88     int n;
     89     while(~scanf("%d", &n)) {
     90         memset(head, -1, sizeof(head)); tot = 0;
     91         memset(out, 0, sizeof(out)); memset(in, 0, sizeof(in));
     92         S = n + 1, T = n + 2, SS = n + 3, ST = n + 4;
     93         for(int i = 1; i <= n; i++) {
     94             int k; scanf("%d", &k);
     95             while(k--) {
     96                 int x; scanf("%d", &x);
     97                 out[i]++; in[x]++;
     98                 Add(i, x, INF);
     99             }
    100         }
    101         for(int i = 1; i <= n; i++) {
    102             if(!out[i]) Add(i, T, INF);
    103             if(!in[i]) Add(S, i, INF);
    104             int deg = in[i] - out[i];
    105             if(deg > 0) Add(SS, i, deg);
    106             else if(deg < 0) Add(i, ST, -deg);
    107         }
    108         Add(T, S, INF);
    109         ISAP(SS, ST, ST + 1);
    110         int ans = edge[tot-1].cap;
    111         Delete();
    112         ans -= ISAP(T, S, T + 1);
    113         printf("%d
    ", ans);
    114         Update(n);
    115         int cur = head[S];
    116         for(int k = 1; k <= ans; k++) {
    117             for(int i = cur; ~i; i = edge[i].nxt) {
    118                 if(!(i & 1) && edge[i^1].cap) {
    119                     int v = edge[i].v;
    120                     edge[i^1].cap--;
    121                     printf("%d", v);
    122                     Dfs(edge[i].v);
    123                     puts("");
    124                     cur = i;
    125                     break;
    126                 }
    127             }
    128         }
    129     }
    130     return 0;
    131 }

    写法二:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define N 210
      4 #define INF 0x3f3f3f3f
      5 struct Edge {
      6     int u, v, nxt, cap;
      7 } edge[N*N];
      8 int head[N], tot, dis[N], cur[N], pre[N], gap[N], in[N], out[N], S, T, SS, ST, n;
      9 
     10 void Add(int u, int v, int cap) {
     11     edge[tot].u = u, edge[tot].v = v, edge[tot].nxt = head[u], edge[tot].cap = cap, head[u] = tot++;
     12     edge[tot].u = v, edge[tot].v = u, edge[tot].nxt = head[v], edge[tot].cap = 0, head[v] = tot++;
     13 }
     14 
     15 int BFS(int T) {
     16     memset(dis, INF, sizeof(dis));
     17     memset(gap, 0, sizeof(gap));
     18     memcpy(cur, head, sizeof(cur));
     19     dis[T] = 0, gap[0]++;
     20     queue<int> que; que.push(T);
     21     while(!que.empty()) {
     22         int u = que.front(); que.pop();
     23         for(int i = head[u]; ~i; i = edge[i].nxt) {
     24             int v = edge[i].v;
     25             if(dis[v] == INF) {
     26                 dis[v] = dis[u] + 1;
     27                 gap[dis[v]]++;
     28                 que.push(v);
     29             }
     30         }
     31     }
     32 }
     33 
     34 int ISAP(int S, int T, int n) {
     35     BFS(T);
     36     int u = pre[S] = S, i, index, flow, ans = 0;
     37     while(dis[S] < n) {
     38         if(u == T) {
     39             flow = INF;
     40             for(i = S; i != T; i = edge[cur[i]].v)
     41                 if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
     42             for(i = S; i != T; i = edge[cur[i]].v)
     43                 edge[cur[i]].cap -= flow, edge[cur[i]^1].cap += flow;
     44             ans += flow, u = index;
     45         }
     46         for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap && dis[edge[i].v] + 1 == dis[u]) break;
     47         if(~i) {
     48             cur[u] = i; pre[edge[i].v] = u; u = edge[i].v;
     49         } else {
     50             if(--gap[dis[u]] == 0) break;
     51             int md = n;
     52             for(int i = head[u]; ~i; i = edge[i].nxt)
     53                 if(edge[i].cap && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
     54             gap[dis[u] = md + 1]++;
     55             u = pre[u];
     56         }
     57     }
     58     return ans;
     59 }
     60 
     61 void Delete() {
     62     for(int i = head[SS]; ~i; i = edge[i].nxt) edge[i].cap = edge[i^1].cap = 0;
     63     for(int i = head[ST]; ~i; i = edge[i].nxt) edge[i].cap = edge[i^1].cap = 0;
     64     edge[tot-1].cap = edge[(tot-1)^1].cap = 0;
     65 }
     66 
     67 void Update(int n) {
     68     for(int u = 1; u <= n; u++) {
     69         for(int i = head[u]; ~i; i = edge[i].nxt) {
     70             if(edge[i].v == S || edge[i].v == T || (i & 1)) continue;
     71             edge[i^1].cap++;
     72         }
     73     }
     74 }
     75 
     76 void Dfs(int u) {
     77     for(int i = head[u]; ~i; i = edge[i].nxt) {
     78         int v = edge[i].v;
     79         if(i & 1 || !edge[i^1].cap || v > n) continue;
     80         edge[i^1].cap--;
     81         printf(" %d", v);
     82         Dfs(v); break;
     83     }
     84 }
     85 
     86 void Solve() {
     87     for(int u = 1; u <= n; u++) {
     88         for(int i = head[u]; ~i; i = edge[i].nxt) {
     89             int v = edge[i].v;
     90             if(i & 1) continue;
     91             edge[i^1].cap++;
     92         }
     93     }
     94     for(int i = head[S]; ~i; i = edge[i].nxt) {
     95         if(i & 1) continue;
     96         while(edge[i^1].cap) {
     97             edge[i^1].cap--;
     98             int v = edge[i].v;
     99             printf("%d", v);
    100             Dfs(v); puts("");
    101         }
    102     }
    103 }
    104 
    105 int main() {
    106     while(~scanf("%d", &n)) {
    107         memset(head, -1, sizeof(head)); tot = 0;
    108         memset(out, 0, sizeof(out)); memset(in, 0, sizeof(in));
    109         S = n + 1, T = n + 2, SS = n + 3, ST = n + 4;
    110         for(int i = 1; i <= n; i++) {
    111             int k; scanf("%d", &k);
    112             while(k--) {
    113                 int x; scanf("%d", &x);
    114                 out[i]++; in[x]++;
    115                 Add(i, x, INF);
    116             }
    117         }
    118         for(int i = 1; i <= n; i++) {
    119             if(!out[i]) Add(i, T, INF);
    120             if(!in[i]) Add(S, i, INF);
    121             int deg = in[i] - out[i];
    122             if(deg > 0) Add(SS, i, deg);
    123             else if(deg < 0) Add(i, ST, -deg);
    124         }
    125         ISAP(SS, ST, ST + 1);
    126         Add(T, S, INF);
    127         int ans = ISAP(SS, ST, ST + 1);
    128         printf("%d
    ", ans);
    129         Solve();
    130     }
    131     return 0;
    132 }
  • 相关阅读:
    Dubbo集群配置和官方文档
    Lock wait timeout exceeded
    Too many connections
    mybatis 批量更新 Parameter '__frch_item_0' not found. Available parameters are [list]
    base64文件转MultipartFile文件
    base64之js压缩图片
    NotSupportedError Only secure origins are allowed
    安装MySQL时候最后一步报无法定位程序输入点fesetround于动态链接库MSVCR120.dll
    2018年总结
    java开发之多线程基础篇
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6736429.html
Copyright © 2020-2023  润新知