• [kuangbin]带你飞之'网络流'专题


    专题十一 网络流

    带飞网址 ✈


    √ POJ 3281 Dining
    √ POJ 1087 A Plug for UNIX
    √ POJ 2195 Going Home
    √ POJ 2516 Minimum Cost
    √ POJ 1459 Power Network
    √ HDU 4280 Island Transport
    √ HDU 4292 Food
    √ HDU 4289 Control
    √ UVA 10480 Sabotage
    HDU 2732 Leapin' Lizards
    HDU 3338 Kakuro Extension
    HDU 3605 Escape
    √ HDU 3081 Marriage Match II
    √ HDU 3416 Marriage Match IV

    // poj 3281 最大流 水

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<queue>
      4 #define INF 0x3f3f3f3f
      5 using namespace std;
      6 
      7 inline int read() {
      8     char c=getchar();int x=0,f=1;
      9     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     10     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     11     return x*f;
     12 }
     13 
     14 const int MAXN = 30000+5;
     15 const int MAXE = 20400+5;
     16 
     17 int num;
     18 int head[MAXN];
     19 struct node {
     20     int v, flow;
     21     int next;
     22 } edge[MAXE];
     23 
     24 inline void add(int x, int y, int w) {
     25     edge[num].v = y;
     26     edge[num].flow = w;
     27     edge[num].next = head[x];
     28     head[x] = num++;
     29 }
     30 
     31 int n, cows, food, drink;
     32 int cur[MAXN], dis[MAXN];
     33 
     34 bool bfs() {
     35     for(int i = 1; i <= n; ++i) dis[i] = 0;
     36     dis[1] = 1;
     37     queue<int> q;
     38     q.push(1);
     39     while(!q.empty()) {
     40         int u = q.front();
     41         q.pop();
     42         for(int i = head[u]; i != -1; i = edge[i].next) {
     43             int v = edge[i].v;
     44             if(!dis[v] && edge[i].flow) {
     45                 dis[v] = dis[u] + 1;
     46                 q.push(v);
     47             }
     48         }
     49     }
     50     return dis[n] != 0;
     51 }
     52 
     53 int dfs(int u, int f) {
     54     if(u == n || (!f)) return f;
     55     int flow = 0;
     56     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     57         int v = edge[i].v;
     58         if(dis[v] == dis[u] + 1) {
     59             int di = dfs(v, min(f, edge[i].flow));
     60             if(di > 0) {
     61                 flow += di;
     62                 f -= di;
     63                 edge[i].flow -= di;
     64                 edge[i^1].flow += di;
     65                 if(!f) break;
     66             }
     67         }
     68     }
     69     if(!flow) dis[u] = -1;
     70     return flow;
     71 }
     72 
     73 int Dinic() {
     74     int ans = 0;
     75     while(bfs()) {
     76         for(int i = 1; i <= n; ++i) cur[i] = head[i];
     77         ans += dfs(1, INF);
     78     }
     79     return ans;
     80 }
     81 
     82 
     83 int main() {
     84     cows = read(); food = read(); drink = read();
     85     n = cows*2 + food + drink + 2;
     86     num = 0;
     87     for(int i = 1; i <= n; ++i) head[i] = -1;
     88     for(int i = 2; i <= 1+food; ++i) {
     89         add(1, i, 1);
     90         add(i, 1, 0);
     91     }
     92     for(int i = 2+food+cows*2; i <= 1+food+cows*2+drink; ++i) {
     93         add(i, n, 1);
     94         add(n, i, 0);
     95     }
     96     int fn, dn, x;
     97     for(int i = 2+food; i <= 1+food+cows; ++i) {
     98         fn = read(); dn = read();
     99         for(int j = 0; j != fn; ++j) {
    100             x = read();
    101             add(1+x, i, 1);
    102             add(i, 1+x, 0);
    103         }
    104         for(int j = 0; j != dn; ++j) {
    105             x = read();
    106             add(i+cows, 1+food+cows*2+x, 1);
    107             add(1+food+cows*2+x, i+cows, 0);
    108         }
    109         add(i, i+cows, 1);
    110         add(i+cows, i, 0);
    111     }
    112     printf("%d
    ", Dinic());
    113     return 0;
    114 }
    View Code

     // poj 1087 最大流 + flody

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<string>
      5 #include<queue>
      6 #include<map>
      7 #include<set>
      8 #define INF 0x3f3f3f3f
      9 using namespace std;
     10 const int MAXN = 10000+5;
     11 const int MAXE = 80000+5;
     12 typedef pair<string, string> Pair;
     13 
     14 int num;
     15 int head[MAXN];
     16 struct node {
     17     int v, w;
     18     int next;
     19 } edge[MAXE];
     20 
     21 inline void add(int x, int y, int w) {
     22     edge[num].v = y;
     23     edge[num].w = w;
     24     edge[num].next = head[x];
     25     head[x] = num++;
     26 }
     27 
     28 int cz, things, type, n;
     29 string name;
     30 map<int, string> id;
     31 string a, b;
     32 vector<Pair> wp;
     33 vector<Pair> tp;
     34 int G[MAXN][MAXN];
     35 
     36 int cur[MAXN];
     37 int dis[MAXN];
     38 
     39 bool bfs() {
     40     for(int i = 1; i <= n; ++i) dis[i] = 0;
     41     dis[1] = 1;
     42     queue<int> q;
     43     q.push(1);
     44     while(!q.empty()) {
     45         int u = q.front();
     46         q.pop();
     47         for(int i = head[u]; i != -1; i = edge[i].next) {
     48             int v = edge[i].v;
     49             if(!dis[v] && edge[i].w) {
     50                 dis[v] = dis[u] + 1;
     51                 q.push(v);
     52             }
     53         }
     54     }
     55     return dis[n] != 0;
     56 }
     57 
     58 int dfs(int u, int f) {
     59     if(u == n || (!f)) return f;
     60     int flow = 0;
     61     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     62         int v = edge[i].v;
     63         if(dis[v] == dis[u] + 1) {
     64             int di = dfs(v, min(f, edge[i].w));
     65             if(di) {
     66                 flow += di;
     67                 f -= di;
     68                 edge[i].w -= di;
     69                 edge[i^1].w += di;
     70                 if(!f) break;
     71             }
     72         }
     73     }
     74     if(!f) dis[u] = -1;
     75     return flow;
     76 }
     77 
     78 int Dinic() {
     79     int ans = 0;
     80     while(bfs()) {
     81         for(int i = 1; i <= n; ++i) cur[i] = head[i];
     82         ans += dfs(1, INF);
     83     }
     84     return things - ans;
     85 }
     86 
     87 void flody() {
     88     map<int, string> tt;
     89     map<string, int> id2;
     90     int cnt = 0;
     91     for(int i = 0; i != type; ++i) {
     92         cin >> b >> a;
     93         if(!id2.count(a)) tt[++cnt] = a, id2[a] = cnt;
     94         if(!id2.count(b)) tt[++cnt] = b, id2[b] = cnt;
     95         G[id2[a]][id2[b]] = 1;
     96     }
     97     for(int k = 1; k <= cnt; ++k) {
     98         for(int i = 1; i <= cnt; ++i) {
     99             if(!G[i][k]) continue;
    100             for(int j = 1; j <= cnt; ++j) {
    101                 if(G[k][j]) G[i][j] = 1;
    102             }
    103         }
    104     }
    105     type = 0;
    106     for(int i = 1; i <= cnt; ++i) {
    107         for(int j = 1; j <= cnt; ++j) {
    108             if(G[i][j]) {
    109                 tp.push_back(make_pair(tt[i], tt[j]));
    110                 ++type;
    111             }
    112         }
    113     }
    114     //printf("----%d
    ", type);
    115 }
    116 
    117 int main() {
    118     scanf("%d", &cz);
    119     for(int i = 2; i <= 1+cz; ++i) {
    120         cin >> name;
    121         id[i] = name;
    122     }
    123     scanf("%d", &things);
    124     for(int i = 0; i != things; ++i) {
    125         cin >> a >> b;
    126         wp.push_back(make_pair(a, b));
    127     }
    128     scanf("%d", &type);
    129     flody();
    130     n = cz + things + type + 2;
    131     num = 0;
    132     for(int i = 1; i <= n; ++i) head[i] = -1;
    133     for(int i = 2; i <= 1+cz; ++i) {
    134         add(1, i, 1);
    135         add(i, 1, 0);
    136     }
    137     for(int i = 2+cz+type; i <= 1+cz+type+things; ++i) {
    138         add(i, n, 1);
    139         add(n, i, 0);
    140     }
    141     for(int i = 0; i != wp.size(); ++i) {
    142         for(int j = 2; j <= 1+cz; ++j) {
    143             if(id[j] == wp[i].second) {
    144                 add(j, 2+cz+type+i, 1);
    145                 add(2+cz+type+i, j, 0);
    146                 break;
    147             }
    148         }
    149     }
    150     for(int i = 0; i != tp.size(); ++i) {
    151         a = tp[i].first; b = tp[i].second;
    152         for(int j = 2; j <= 1+cz; ++j) {
    153             if(id[j] == a) {
    154                 add(j, 2+cz+i, 1);
    155                 add(2+cz+i, j, 0);
    156                 break;
    157             }
    158         }
    159         for(int j = 0; j != wp.size(); ++j) {
    160             if(b == wp[j].second) {
    161                 add(2+cz+i, 2+cz+type+j, 1);
    162                 add(2+cz+type+j, 2+cz+i, 0);
    163             }
    164         }
    165     }
    166     printf("%d
    ", Dinic());
    167     return 0;
    168 }
    View Code

     // poj 2195//KM写的。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<fstream>
      5 #include<iostream>
      6 #include<string>
      7 #include<functional>
      8 #include<algorithm>
      9 #include<sstream>
     10 #include<iomanip>
     11 #include<vector>
     12 #include<queue>
     13 #include<stack>
     14 #include<set>
     15 #include<map>
     16 #define read(n) n = read_n()
     17 #define rep(i, n) for(int i=0;i!=n;++i)
     18 #define per(i, n) for(int i=n-1;i>=0;--i)
     19 #define Rep(i, sta, n) for(int i=sta;i!=n;++i)
     20 #define rep1(i, n) for(int i=1;i<=n;++i)
     21 #define per1(i, n) for(int i=n;i>=1;--i)
     22 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
     23 #define L k<<1
     24 #define R k<<1|1
     25 #define mid (tree[k].l+tree[k].r)>>1
     26 #define eps 1e-10
     27 using namespace std;
     28 typedef long long ll;
     29 typedef pair<int,int> Pair;
     30 const int INF = 0x3f3f3f3f;
     31 
     32 inline int read_n() {
     33     char c=getchar();int x=0,f=1;
     34     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     35     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     36     return x*f;
     37 }
     38 inline void put(int a) {
     39     if(a<0){putchar('-');a=-a;}
     40     if(a>9)put(a/10);
     41     putchar(a%10+'0');
     42 }
     43 // -----------------------------------------------------
     44 const int MAXN = 100+5;
     45 
     46 int r, c;
     47 int n, m;
     48 int w[MAXN][MAXN];
     49 
     50 int love[MAXN];
     51 bool visx[MAXN], visy[MAXN];
     52 int cx[MAXN], cy[MAXN];
     53 
     54 bool dfs(int u) {
     55     visx[u] = true;
     56     for(int v = 1; v <= m; ++v) {
     57         if(!visy[v] && cx[u] + cy[v] == w[u][v]) {
     58             visy[v] = true;
     59             if(!love[v] || dfs(love[v])) {
     60                 love[v] = u;
     61                 return true;
     62             }
     63         }
     64     }
     65     return false;
     66 }
     67 
     68 int KM() {
     69     rep1(i, m) love[i] = 0;
     70     rep1(i, n) {
     71         while(1) {
     72             int d = INF;
     73             rep1(j, n) visx[j] = visy[j] = false;
     74             if(dfs(i)) break;
     75             for(int u = 1; u <= n; ++u) {
     76                 if(visx[u]) {
     77                     for(int v = 1; v <= m; ++v) {
     78                         if(!visy[v]) {
     79                             d = min(d, cx[u] + cy[v] - w[u][v]);
     80                         }
     81                     }
     82                 }
     83             }
     84             rep1(u, n) if(visx[u]) cx[u] -= d;
     85             rep1(v, m) if(visy[v]) cy[v] += d;
     86         }
     87     }
     88     int ans = 0;
     89     rep1(i, m) ans += w[love[i]][i];
     90     return -ans;
     91 }
     92 
     93 int main() {
     94     while(scanf("%d%d", &r, &c) == 2 && r) {
     95         n = m = 0;
     96         rep1(i, 100) love[i] = cy[i] = 0, cx[i] = -INF;
     97         char p[MAXN];
     98         vector<Pair> man, house;
     99         rep(i, r) {
    100             scanf("%s", p);
    101             rep(j, c) {
    102                 if(p[j] == 'm') ++n, man.push_back(make_pair(i, j));
    103                 if(p[j] == 'H') ++m, house.push_back(make_pair(i, j));
    104             }
    105         }
    106         rep(i, man.size()) {
    107             rep(j, house.size()) {
    108                 w[i+1][j+1] = -abs(man[i].first - house[j].first) - abs(man[i].second - house[j].second);
    109                 cx[i+1] = max(cx[i+1], w[i+1][j+1]);
    110             }
    111         }
    112         printf("%d
    ", KM());
    113     }
    114     return 0;
    115 }
    View Code

     // poj 2516 最小费用最大流 拆图

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-11-11 22:37:28
      7  * @LastEditTime: 2019-11-12 11:13:39
      8  */
      9 #include<cstdio>
     10 #include<ctime>
     11 #include<algorithm>
     12 #include<stack>
     13 #include<map>
     14 using namespace std;
     15 const int INF = 0x3f3f3f3f;
     16 typedef pair<int,int> Pair;
     17 const int MAXN = 800+5;
     18 const int MAXE = 102000+5;
     19 
     20 int num;
     21 int head[MAXN];
     22 struct node {
     23     int v, flow, dis;
     24     int next;
     25 } edge[MAXE];
     26 
     27 inline void add(int x, int y, int w, int d) {
     28     edge[num].v = y;
     29     edge[num].flow = w;
     30     edge[num].dis = d;
     31     edge[num].next = head[x];
     32     head[x] = num++;
     33 }
     34 
     35 int n, m, k, sum;
     36 int S, T;
     37 
     38 int maxflow, mincost;
     39 int flow[MAXN], dis[MAXN];
     40 int pre[MAXN], last[MAXN];
     41 bool vis[MAXN];
     42 
     43 bool spfa() {
     44     for(int i = 1; i <= T; ++i) flow[i] = dis[i] = INF, vis[i] = false;
     45     dis[S] = 0;
     46     vis[S] = true;
     47     pre[T] = -1;
     48     stack<int> q;
     49     q.push(S);
     50     while(!q.empty()) {
     51         int u = q.top();
     52         q.pop();
     53         vis[u] = false;
     54         for(int i = head[u]; i != -1; i = edge[i].next) {
     55             int v = edge[i].v;
     56             if(edge[i].flow && dis[v] > dis[u] + edge[i].dis) {
     57                 dis[v] = dis[u] + edge[i].dis;
     58                 pre[v] = u;
     59                 last[v] = i;
     60                 flow[v] = min(flow[u], edge[i].flow);
     61                 if(!vis[v]) {
     62                     vis[v] = true;
     63                     q.push(v);
     64                 }
     65             }
     66         }
     67     }
     68     return  pre[T] != -1;
     69 }
     70 
     71 bool MCMF() {
     72     maxflow = mincost = 0;
     73     while(spfa()) {
     74         maxflow += flow[T];
     75         mincost += flow[T]*dis[T];
     76         int u = T;
     77         while(u != S) {
     78             edge[last[u]].flow -= flow[T];
     79             edge[last[u]^1].flow += flow[T];
     80             u = pre[u];
     81         }
     82     }
     83     return maxflow == sum;
     84 }
     85 
     86 int need[155][155], have[155][155], cost[155][155][155];
     87 
     88 void draw(int k_num) {
     89     S = 1; T = 2+m+n;
     90     num = sum = 0;
     91     for(int i = 1; i <= T; ++i) head[i] = -1;
     92     for(int i = 2; i <= 1+m; ++i) {
     93         add(S, i, have[i-1][k_num], 0);
     94         add(i, S, 0, 0);
     95     }
     96     for(int i = 2; i <= 1+m; ++i) {
     97         for(int j = 2+m; j <= 1+m+n; ++j) {
     98             add(i, j, INF, cost[j-1-m][i-1][k_num]);
     99             add(j, i, 0, -cost[j-1-m][i-1][k_num]);
    100         }
    101     }
    102     for(int i = 2+m; i <= 1+m+n; ++i) {
    103         add(i, T, need[i-1-m][k_num], 0);
    104         add(T, i, 0, 0);
    105         sum += need[i-1-m][k_num];
    106     }
    107 }
    108 
    109 int solve() {
    110     int ans = 0;
    111     for(int i = 1; i <= k; ++i) {
    112         draw(i);
    113         if(MCMF()) ans += mincost;
    114         else return -1;
    115     }
    116     return ans;
    117 }
    118 
    119 void input() {
    120     int x;
    121     for(int i = 1; i <= n; ++i) {
    122         for(int j = 1; j <= k; ++j) {
    123             scanf("%d", &x);
    124             need[i][j] = x;
    125         }
    126     }
    127     for(int i = 1; i <= m; ++i) {
    128         for(int j = 1; j <= k; ++j) {
    129             scanf("%d", &x);
    130             have[i][j] = x;
    131         }
    132     }
    133     for(int i = 1; i <= k; ++i) {
    134         for(int u = 1; u <= n; ++u) {
    135             for(int v = 1; v <= m; ++v) {
    136                 scanf("%d", &x);
    137                 cost[u][v][i] = x;
    138             }
    139         }
    140     }
    141 }
    142 
    143 int main() {
    144     while(1) {
    145         scanf("%d%d%d", &n, &m, &k);
    146         if(!n) break;
    147         input();
    148         printf("%d
    ", solve());
    149     }
    150     return 0;
    151 }
    View Code

     // poj 1459 最大流 水

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<queue>
      4 #define INF 0x3f3f3f3f
      5 using namespace std;
      6 const int MAXN = 102+5;
      7 const int MAXE = 40200+5;
      8 
      9 int num;
     10 int head[MAXN];
     11 struct node {
     12     int v, flow;
     13     int next;
     14 } edge[MAXE];
     15 
     16 inline void add(int x, int y, int w) {
     17     edge[num].v = y;
     18     edge[num].flow = w;
     19     edge[num].next = head[x];
     20     head[x] = num++;
     21 }
     22 
     23 int n, np, nc, m;
     24 
     25 int dis[MAXN], cur[MAXN];
     26 bool vis[MAXN];
     27 
     28 bool bfs() {
     29     for(int i = 1; i <= n; ++i) dis[i] = 0;
     30     dis[1] = 1;
     31     queue<int> q;
     32     q.push(1);
     33     while(!q.empty()) {
     34         int u = q.front();
     35         q.pop();
     36         for(int i = head[u]; i != -1; i = edge[i].next) {
     37             int v = edge[i].v;
     38             if(!dis[v] && edge[i].flow) {
     39                 dis[v] = dis[u] + 1;
     40                 q.push(v);
     41             }
     42         }
     43     }
     44     return dis[n] != 0;
     45 }
     46 
     47 int dfs(int u, int f) {
     48     if(u == n || (!f)) return f;
     49     int flow = 0;
     50     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     51         int v = edge[i].v;
     52         if(dis[v] == dis[u] + 1) {
     53             int di = dfs(v, min(f, edge[i].flow));
     54             if(di > 0) {
     55                 f -= di;
     56                 flow += di;
     57                 edge[i].flow -= di;
     58                 edge[i^1].flow += di;
     59                 if(!f) break;
     60             }
     61         }
     62     }
     63     if(!flow) dis[u] = -1;
     64     return flow;
     65 }
     66 
     67 int Dinic() {
     68     int ans = 0;
     69     while(bfs()) {
     70         for(int i = 1; i <= n; ++i) cur[i] = head[i];
     71         ans += dfs(1, INF);
     72     }
     73     return ans;
     74 }
     75 
     76 int main() {
     77     while(scanf("%d%d%d%d", &n, &np, &nc, &m) == 4) {
     78         n = n+2;
     79         num = 0;
     80         for(int i = 1; i <= n; ++i) head[i] = -1;
     81         char c;
     82         int x, y, w;
     83         for(int i = 0; i != m; ++i) {
     84             c = getchar();
     85             while(c != '(') c = getchar();
     86             scanf("%d,%d)%d", &x, &y, &w);
     87             add(x+2, y+2, w);
     88             add(y+2, x+2, 0);
     89         }
     90         for(int i = 0; i != np; ++i) {
     91             c = getchar();
     92             while(c != '(') c = getchar();
     93             scanf("%d)%d", &x, &w);
     94             add(1, x+2, w);
     95             add(x+2, 1, 0);
     96         }
     97         for(int i = 0; i != nc; ++i) {
     98             c = getchar();
     99             while(c != '(') c = getchar();
    100             scanf("%d)%d", &x, &w);
    101             add(x+2, n, w);
    102             add(n, x+2, 0);
    103         }
    104         printf("%d
    ", Dinic());
    105     }
    106     return 0;
    107 }
    View Code

     // hdu 4280 最大流水(无向图 反向边权值和正向边权值相等)

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<queue>
      4 #define INF 0x3f3f3f3f
      5 using namespace std;
      6 
      7 inline int read() {
      8     char c=getchar();int x=0,f=1;
      9     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     10     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     11     return x*f;
     12 }
     13 
     14 const int MAXN = 100002+5;
     15 const int MAXE = 200002+5;
     16 
     17 int num;
     18 int head[MAXN];
     19 struct node {
     20     int v, flow;
     21     int next;
     22 } edge[MAXE];
     23 
     24 inline void add(int x, int y, int w) {
     25     edge[num].v = y;
     26     edge[num].flow = w;
     27     edge[num].next = head[x];
     28     head[x] = num++;
     29 }
     30 
     31 int n, m;
     32 int S, T;
     33 int dis[MAXN], cur[MAXN];
     34 
     35 int q[MAXN];
     36 bool bfs() {
     37     for(int i = 1; i <= n; ++i) dis[i] = 0;
     38     dis[S] = 1;
     39     int l = 1, r = 1;
     40     q[1] = S;
     41     while(l <= r) {
     42         int u = q[l];
     43         if(u == T) return true;
     44         ++l;
     45         for(int i = head[u]; i != -1; i = edge[i].next) {
     46             int v = edge[i].v;
     47             if(!dis[v] && edge[i].flow) {
     48                 dis[v] = dis[u] + 1;
     49                 q[++r] = v;
     50             }
     51         }
     52     }
     53     return dis[T] != 0;
     54 }
     55 
     56 int dfs(int u, int f) {
     57     if(u == T || (!f)) return f;
     58     int flow = 0;
     59     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     60         int v = edge[i].v;
     61         if(dis[v] == dis[u] + 1) {
     62             int di = dfs(v, min(f, edge[i].flow));
     63             if(di > 0) {
     64                 f -= di;
     65                 flow += di;
     66                 edge[i].flow -= di;
     67                 edge[i^1].flow += di;
     68                 if(!f) break;
     69             }
     70         }
     71     }
     72     if(!flow) dis[u] = -1;
     73     return flow;
     74 }
     75 
     76 int Dinic() {
     77     int ans = 0;
     78     while(bfs()) {
     79         for(int i = 1; i <= n; ++i) cur[i] = head[i];
     80         ans += dfs(S, INF);
     81     }
     82     return ans;
     83 }
     84 
     85 int main() {
     86     int qaq = read();
     87     while(qaq--) {
     88         n = read(); m = read();
     89         int l = INF, r = -INF;
     90         int x, y, w;
     91         for(int i = 1; i <= n; ++i) {
     92             x = read(); y = read();
     93             if(x < l) S = i, l = x;
     94             if(x > r) T = i, r = x;
     95             head[i] = -1;
     96         }
     97         num = 0;
     98         for(int i = 0; i != m; ++i) {
     99             x = read(); y = read(); w = read();
    100             add(x, y, w);
    101             add(y, x, w);
    102         }
    103         printf("%d
    ", Dinic());
    104     }
    105     return 0;
    106 }
    View Code

     // hdu 4292 最大流 拆点 水

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<queue>
      4 #pragma comment(linker, "/STACK:102400000,102400000")
      5 #define INF 0x3f3f3f3f
      6 using namespace std;
      7 const int MAXN = 802+5;
      8 const int MAXE = 201200+5;
      9 
     10 int num;
     11 int head[MAXN];
     12 struct node {
     13     int v, flow;
     14     int next;
     15 } edge[MAXE];
     16 
     17 inline void add(int x, int y, int w) {
     18     edge[num].v = y;
     19     edge[num].flow = w;
     20     edge[num].next = head[x];
     21     head[x] = num++;
     22 }
     23 
     24 int n, f, d;
     25 int S, T;
     26 
     27 int dis[MAXN], cur[MAXN];
     28 
     29 bool bfs() {
     30     for(int i = 1; i <= T; ++i) dis[i] = 0;
     31     dis[S] = 1;
     32     queue<int> q;
     33     q.push(S);
     34     while(!q.empty()) {
     35         int u = q.front();
     36         q.pop();
     37         for(int i = head[u]; i != -1; i = edge[i].next) {
     38             int v = edge[i].v;
     39             if(!dis[v] && edge[i].flow) {
     40                 dis[v] = dis[u] + 1;
     41                 q.push(v);
     42             }
     43         }
     44     }
     45     return dis[T] != 0;
     46 }
     47 
     48 int dfs(int u, int f) {
     49     if(u == T || (!f)) return f;
     50     int flow = 0;
     51     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     52         int v = edge[i].v;
     53         if(dis[v] == dis[u] + 1) {
     54             int di = dfs(v, min(f, edge[i].flow));
     55             if(di > 0) {
     56                 f -= di;
     57                 flow += di;
     58                 edge[i].flow -= di;
     59                 edge[i^1].flow += di;
     60                 if(!f) break;
     61             }
     62         }
     63     }
     64     if(!flow) dis[u] = -1;
     65     return flow;
     66 }
     67 
     68 int Dinic() {
     69     int ans = 0;
     70     while(bfs()) {
     71         for(int i = 1; i <= T; ++i) cur[i] = head[i];
     72         ans += dfs(S, INF);
     73     }
     74     return ans;
     75 }
     76 
     77 int main() {
     78     while(scanf("%d%d%d", &n, &f, &d) == 3) {
     79         S = 1; T = f+n*2+d+2;
     80         num = 0;
     81         for(int i = 1; i <= T; ++i) head[i] = -1;
     82         int x;
     83         for(int i = 0; i != f; ++i) {
     84             scanf("%d", &x);
     85             add(1, 2+i, x);
     86             add(2+i, 1, 0);
     87         }
     88         for(int i = 0; i != d; ++i) {
     89             scanf("%d", &x);
     90             add(2+f+n*2+i, T, x);
     91             add(T, 2+f+n*2+i, 0);
     92         }
     93         char bin[400];
     94         for(int p = 0; p != n; ++p) {
     95             scanf("%s", bin);
     96             for(int i = 0; i != f; ++i) {
     97                 if(bin[i] == 'Y') {
     98                     add(2+i, 2+f+p, 1);
     99                     add(2+f+p, 2+i, 0);
    100                 }
    101             }
    102         }
    103         for(int i = 2+f; i <= 1+f+n; ++i) {
    104             add(i, i+n, 1);
    105             add(i+n, i, 0);
    106         }
    107         for(int p = 0; p != n; ++p) {
    108             scanf("%s", bin);
    109             for(int i = 0; i != d; ++i) {
    110                 if(bin[i] == 'Y') {
    111                     add(2+f+n+p, 2+f+n*2+i, 1);
    112                     add(2+f+n*2+i, 2+f+n+p, 0);
    113                 }
    114             }
    115         }
    116         printf("%d
    ", Dinic());
    117     }
    118     return 0;
    119 }
    View Code

     // hdu 4289 最小割最大流定理

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-11-14 23:38:16
      7  * @LastEditTime: 2019-11-15 00:12:20
      8  */
      9 #include<cstdio>
     10 #include<algorithm>
     11 #define INF 0x3f3f3f3f
     12 using namespace std;
     13 const int MAXN = 400+5;
     14 const int MAXE = 80400+5;
     15 
     16 int num;
     17 int head[MAXN];
     18 struct node {
     19     int v, flow;
     20     int next;
     21 } edge[MAXE];
     22 
     23 inline void add(int x, int y, int w) {
     24     edge[num].v = y;
     25     edge[num].flow = w;
     26     edge[num].next = head[x];
     27     head[x] = num++;
     28 }
     29 
     30 int n, m;
     31 int S, T;
     32 int cost[MAXN];
     33 
     34 int dis[MAXN], cur[MAXN];
     35 
     36 int q[MAXN], l, r;
     37 bool bfs() {
     38     for(int i = 1; i <= n*2; ++i) dis[i] = 0;
     39     dis[S] = 1;
     40     q[1] = S;
     41     l = r = 1;
     42     while(l <= r) {
     43         int u = q[l++];
     44         for(int i = head[u]; i != -1; i = edge[i].next) {
     45             int v = edge[i].v;
     46             if(!dis[v] && edge[i].flow) {
     47                 dis[v] = dis[u] + 1;
     48                 q[++r] = v;
     49             }
     50         }
     51     }
     52     return dis[T];
     53 }
     54 
     55 int dfs(int u, int f) {
     56     if(u == T || (!f)) return f;
     57     int flow = 0;
     58     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     59         int v = edge[i].v;
     60         if(dis[v] == dis[u] + 1) {
     61             int di = dfs(v, min(f, edge[i].flow));
     62             if(di) {
     63                 f -= di;
     64                 flow += di;
     65                 edge[i].flow -= di;
     66                 edge[i^1].flow += di;
     67                 if(!f) break;
     68             }
     69         }
     70     }
     71     if(!flow) dis[u] = -1;
     72     return flow;
     73 }
     74 
     75 int Dinic() {
     76     int ans = 0;
     77     while(bfs()) {
     78         for(int i = 1; i <= n*2; ++i) cur[i] = head[i];
     79         ans += dfs(S, INF);
     80     }
     81     return ans;
     82 }
     83 
     84 int main() {
     85     while(scanf("%d%d", &n, &m) == 2) {
     86         scanf("%d%d", &S, &T);
     87         T = T + n;
     88         num = 0;
     89         for(int i = 1; i <= n*2; ++i) head[i] = -1;
     90         for(int i = 1; i <= n; ++i) scanf("%d", &cost[i]);
     91         for(int i = 1; i <= n; ++i) {
     92             add(i, i+n, cost[i]);
     93             add(i+n, i, 0);
     94         }
     95         int x, y;
     96         for(int i = 0; i != m; ++i) {
     97             scanf("%d%d", &x, &y);
     98             add(x+n, y, INF);
     99             add(y, x+n, 0);
    100             add(y+n, x, INF);
    101             add(x, y+n, 0);
    102         }
    103         printf("%d
    ", Dinic());
    104     }
    105     return 0;
    106 }
    View Code

     // uva 10480 最小割集合

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-11-15 00:24:15
      7  * @LastEditTime: 2019-11-15 01:14:42
      8  */
      9 #include<cstdio>
     10 #include<algorithm>
     11 #define INF 0x3f3f3f3f
     12 using namespace std;
     13 const int MAXN = 50+5;
     14 const int MAXE = 1000+5;
     15 
     16 int num;
     17 int head[MAXN];
     18 struct node {
     19     int u, v, flow;
     20     int next;
     21 } edge[MAXE];
     22 
     23 inline void add(int x, int y, int w) {
     24     edge[num].u = x;
     25     edge[num].v = y;
     26     edge[num].flow = w;
     27     edge[num].next = head[x];
     28     head[x] = num++;
     29 }
     30 
     31 int n, m;
     32 
     33 int dis[MAXN], cur[MAXN];
     34 
     35 int q[MAXN], l, r;
     36 bool bfs() {
     37     for(int i = 1; i <= n; ++i) dis[i] = 0;
     38     dis[1] = 1;
     39     q[1] = 1;
     40     l = r = 1;
     41     while(l <= r) {
     42         int u = q[l++];
     43         for(int i = head[u]; i != -1; i = edge[i].next) {
     44             int v = edge[i].v;
     45             if(!dis[v] && edge[i].flow) {
     46                 dis[v] = dis[u] + 1;
     47                 q[++r] = v;
     48             }
     49         }
     50     }
     51     return dis[2];
     52 }
     53 
     54 int dfs(int u, int f) {
     55     if(u == 2 || (!f)) return f;
     56     int flow = 0;
     57     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     58         int v = edge[i].v;
     59         if(dis[v] == dis[u] + 1) {
     60             int di = dfs(v, min(f, edge[i].flow));
     61             if(di) {
     62                 f -= di;
     63                 flow += di;
     64                 edge[i].flow -= di;
     65                 edge[i^1].flow += di;
     66                 if(!f) break;
     67             }
     68         }
     69     }
     70     if(!flow) dis[u] = -1;
     71     return flow;
     72 }
     73 
     74 void Dinic() {
     75     while(bfs()) {
     76         for(int i = 1; i <= n; ++i) cur[i] = head[i];
     77         dfs(1, INF);
     78     }
     79 }
     80 
     81 bool vis[MAXN];
     82 void color(int u) {
     83     vis[u] = true;
     84     for(int i = head[u]; i != -1; i = edge[i].next) {
     85         int v = edge[i].v;
     86         if(!vis[v] && edge[i].flow) color(v);
     87     }
     88 }
     89 
     90 int main() {
     91     while(scanf("%d%d", &n, &m) == 2 && n) {
     92         num = 0;
     93         for(int i = 1; i <= n; ++i) head[i] = -1;
     94         int x, y, w;
     95         for(int i = 0; i != m; ++i) {
     96             scanf("%d%d%d", &x, &y, &w);
     97             add(x, y, w);
     98             add(y, x, w);
     99         }
    100         Dinic();
    101         for(int i = 1; i <= n; ++i) vis[i] = false;
    102         color(1);
    103         for(int u = 1; u <= n; ++u) {
    104             for(int i = head[u]; i != -1; i = edge[i].next) {
    105                 int v = edge[i].v;
    106                 if(vis[u] && !vis[v]) printf("%d %d
    ", u, v);
    107             }
    108         }
    109         printf("
    ");
    110     }
    111     return 0;
    112 }
    View Code

     // hdu 2732  最大流 水

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-11-15 08:50:24
      7  * @LastEditTime: 2019-11-15 10:51:36
      8  */
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<algorithm>
     12 #define INF 0x3f3f3f3f
     13 using namespace std;
     14 const int MAXN = 80000;
     15 const int MAXE = 800000;
     16 
     17 int num;
     18 int head[MAXN];
     19 struct node {
     20     int v, flow;
     21     int next;
     22 } edge[MAXE];
     23 
     24 inline void add(int x, int y, int w) {
     25     edge[num].v = y;
     26     edge[num].flow = w;
     27     edge[num].next = head[x];
     28     head[x] = num++;
     29 }
     30 
     31 int r, c, d;
     32 int n, S, T, sum;
     33 char A[102][102], B[102][102];
     34 
     35 void draw() {
     36     for(int i = 0; i != r; ++i) {
     37         for(int j = 0; j != c; ++j) {
     38             if(A[i][j] == '0') continue;
     39             add(i*c+j+1, i*c+j+1+n, A[i][j]-'0');
     40             add(i*c+j+1+n, i*c+j+1, 0);
     41             if(B[i][j] == 'L') {
     42                 add(S, i*c+j+1, 1);
     43                 add(i*c+j+1, S, 0);
     44                 ++sum;
     45             }
     46             if(i-d<0 || i+d>=r || j-d<0 || j+d>=c) {
     47                 add(i*c+j+1+n, T, INF);
     48                 add(T, i*c+j+1+n, 0);
     49             }
     50             for(int ii = 0; ii <= i; ++ii) {
     51                 int cc = c-1;
     52                 if(ii == i) cc = j;
     53                 for(int jj = 0; jj <= cc; ++jj) {
     54                     if(ii == i && jj == j || A[ii][jj] == '0') continue;
     55                     if(abs(i-ii)+abs(j-jj) <= d) {
     56                         add(i*c+j+1+n, ii*c+jj+1, INF);
     57                         add(ii*c+jj+1, i*c+j+1+n, 0);
     58                         add(ii*c+jj+1+n, i*c+j+1, INF);
     59                         add(i*c+j+1, ii*c+jj+1+n, 0);
     60                     }
     61                 }
     62             }
     63         }
     64     }
     65 }
     66 
     67 int dis[MAXN], cur[MAXN];
     68 
     69 int q[MAXN], ll, rr;
     70 bool bfs() {
     71     for(int i = 0; i <= T; ++i) dis[i] = 0;
     72     dis[S] = 1;
     73     q[1] = S;
     74     ll = rr = 1;
     75     while(ll <= rr) {
     76         int u = q[ll++];
     77         for(int i = head[u]; i != -1; i = edge[i].next) {
     78             int v = edge[i].v;
     79             if(!dis[v] && edge[i].flow) {
     80                 dis[v] = dis[u] + 1;
     81                 q[++rr] = v;
     82             }
     83         }
     84     }
     85     return dis[T];
     86 }
     87 
     88 int dfs(int u, int f) {
     89     if(u == T || (!f)) return f;
     90     int flow = 0;
     91     for(int &i = cur[u]; i != -1; i = edge[i].next) {
     92         int v = edge[i].v;
     93         if(dis[v] == dis[u] + 1) {
     94             int di = dfs(v, min(f, edge[i].flow));
     95             if(di) {
     96                 f -= di;
     97                 flow += di;
     98                 edge[i].flow -= di;
     99                 edge[i^1].flow += di;
    100                 if(!f) break;
    101             }
    102         }
    103     }
    104     if(!flow) dis[u] = -1;
    105     return flow;
    106 }
    107 
    108 int Dinic() {
    109     int ans = 0;
    110     while(bfs()) {
    111         for(int i = 0; i <= T; ++i) cur[i] = head[i];
    112         ans += dfs(S, INF);
    113     }
    114     return sum - ans;
    115 }
    116 
    117 int main() {
    118     int qaq, QAQ = 0;
    119     scanf("%d", &qaq);
    120     while(qaq--) {
    121         scanf("%d%d", &r, &d);
    122         for(int i = 0; i != r; ++i) scanf("%s", A[i]);
    123         for(int i = 0; i != r; ++i) scanf("%s", B[i]);
    124 
    125         c = strlen(A[0]);
    126         n = r*c;
    127         S = 0; T = n*2+1;
    128         num = sum = 0;
    129         for(int i = 0; i <= T; ++i) head[i] = -1;
    130         draw();
    131         int ans = Dinic();
    132         if(!ans) printf("Case #%d: no lizard was left behind.
    ", ++QAQ);
    133         else if(ans == 1) printf("Case #%d: 1 lizard was left behind.
    ", ++QAQ);
    134         else printf("Case #%d: %d lizards were left behind.
    ", ++QAQ, ans);
    135     }
    136     return 0;
    137 }
    View Code

     // hdu 3338 最大流 (巧妙建图)

      1 #include<cstdio>
      2 #include<algorithm>
      3 #define INF 0x3f3f3f3f
      4 using namespace std;
      5 const int MAXN = 800000+5;
      6 const int MAXE = 8000000+5;
      7 
      8 int num;
      9 int head[MAXN];
     10 struct node {
     11     int v, flow;
     12     int next;
     13 } edge[MAXE];
     14 
     15 inline void add(int x, int y, int w) {
     16     edge[num].v = y;
     17     edge[num].flow = w;
     18     edge[num].next = head[x];
     19     head[x] = num++;
     20 }
     21 
     22 int r, c;
     23 char G[105][105][10];
     24 int e_num[105][105];
     25 int n, S, T;
     26 
     27 void draw() {
     28     for(int i = 1; i <= r; ++i) {
     29         for(int j = 1; j <= c; ++j) {
     30             if(G[i][j][0] == 'X' && G[i][j][4] == 'X') continue;
     31             if(G[i][j][0] != '.') {
     32                 if(G[i][j][0] != 'X') {
     33                     int f = (G[i][j][0]-'0')*100+(G[i][j][1]-'0')*10+(G[i][j][2]-'0');
     34                     int rr = i+1;
     35                     while(rr <= r && G[rr][j][0] == '.') {
     36                         add((i-1)*c+j, n+(rr-1)*c+j, 8);
     37                         e_num[rr][j] = num;
     38                         add(n+(rr-1)*c+j, (i-1)*c+j, 0);
     39                         ++rr;
     40                         f -= 1;
     41                     }
     42                     add(S, (i-1)*c+j, f);
     43                     add((i-1)*c+j, S, 0);
     44                 }
     45                 if(G[i][j][4] != 'X') {
     46                     int f = (G[i][j][4]-'0')*100+(G[i][j][5]-'0')*10+(G[i][j][6]-'0');
     47                     int cc = j+1;
     48                     while(cc <= c && G[i][cc][0] == '.') {
     49                         add(n+(i-1)*c+cc, n*2+(i-1)*c+j, 8);
     50                         add(n*2+(i-1)*c+j, n+(i-1)*c+cc, 0);
     51                         ++cc;
     52                         f -= 1;
     53                     }
     54                     add(n*2+(i-1)*c+j, T, f);
     55                     add(T, n*2+(i-1)*c+j, 0);
     56                 }
     57             }
     58         }
     59     }
     60 }
     61 
     62 int dis[MAXN], cur[MAXN];
     63 
     64 int q[MAXN], ll, rr;
     65 bool bfs() {
     66     for(int i = 0; i <= T; ++i) dis[i] = 0;
     67     dis[S] = 1;
     68     q[1] = 0;
     69     ll = rr = 1;
     70     while(ll <= rr) {
     71         int u = q[ll++];
     72         for(int i = head[u]; i != -1; i = edge[i].next) {
     73             int v = edge[i].v;
     74             if(!dis[v] && edge[i].flow) {
     75                 dis[v] = dis[u] + 1;
     76                 q[++rr] = v;
     77             }
     78         }
     79     }
     80     return dis[T];
     81 }
     82 
     83 int dfs(int u, int f) {
     84     if(u == T || (!f)) return f;
     85     int flow = 0;
     86     for(int& i = cur[u]; i != -1; i = edge[i].next) {
     87         int v = edge[i].v;
     88         if(dis[v] == dis[u] + 1) {
     89             int di = dfs(v, min(f, edge[i].flow));
     90             if(di) {
     91                 f -= di;
     92                 flow += di;
     93                 edge[i].flow -= di;
     94                 edge[i^1].flow += di;
     95                 if(!f) break;
     96             }
     97         }
     98     }
     99     if(!flow) dis[u] = -1;
    100     return flow;
    101 }
    102 
    103 void Dinic() {
    104     while(bfs()) {
    105         for(int i = 0; i <= T; ++i) cur[i] = head[i];
    106         dfs(S, INF);
    107     }
    108 }
    109 
    110 void solve() {
    111     Dinic();
    112     int t;
    113     for(int i = 1; i <= r; ++i) {
    114         for(int j = 1; j <= c; ++j) {
    115             if(j != 1) printf(" ");
    116             if(G[i][j][0] != '.') printf("_");
    117             else printf("%d", edge[e_num[i][j]].flow+1);
    118         }
    119         printf("
    ");
    120     }
    121 }
    122 
    123 int main() {
    124     while(scanf("%d%d", &r, &c) == 2) {
    125         n = r*c;
    126         S = 0; T = 3*n+1;
    127         num = 0;
    128         for(int i = 0; i <= T; ++i) head[i] = -1;
    129         for(int i = 1; i <= r; ++i) {
    130             for(int j = 1; j <= c; ++j) {
    131                 scanf("%s", G[i][j]);
    132             }
    133         }
    134         draw();
    135         solve();
    136     }
    137     return 0;
    138 }
    View Code

     // hdu 3605 多重匹配写的。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<fstream>
      5 #include<iostream>
      6 #include<string>
      7 #include<functional>
      8 #include<algorithm>
      9 #include<sstream>
     10 #include<iomanip>
     11 #include<vector>
     12 #include<queue>
     13 #include<stack>
     14 #include<set>
     15 #include<map>
     16 #define read(n) n = read_n()
     17 #define rep(i, n) for(int i=0;i!=n;++i)
     18 #define per(i, n) for(int i=n-1;i>=0;--i)
     19 #define Rep(i, sta, n) for(int i=sta;i!=n;++i)
     20 #define rep1(i, n) for(int i=1;i<=n;++i)
     21 #define per1(i, n) for(int i=n;i>=1;--i)
     22 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
     23 #define L k<<1
     24 #define R k<<1|1
     25 #define mid (tree[k].l+tree[k].r)>>1
     26 #define eps 1e-10
     27 using namespace std;
     28 const int INF = 0x3f3f3f3f;
     29 typedef long long ll;
     30 
     31 inline int read_n() {
     32     char c=getchar();int x=0,f=1;
     33     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     34     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     35     return x*f;
     36 }
     37 // -----------------------------------------------------
     38 const int MAXN = 100000+5;
     39 const int MAXM = 10+5;
     40 const int MAXE = MAXN*MAXM;
     41 
     42 int num;
     43 int head[MAXN];
     44 struct node {
     45     int v, next;
     46 } edge[MAXE];
     47 
     48 inline void add(int x, int y) {
     49     edge[num].v = y;
     50     edge[num].next = head[x];
     51     head[x] = num++;
     52 }
     53 
     54 int n, m;
     55 int maxn[MAXM];
     56 
     57 int cnt[MAXM];
     58 int love[MAXM][MAXN];
     59 bool vis[MAXM];
     60 
     61 bool dfs(int u) {
     62     for(int i = head[u]; i != -1; i = edge[i].next) {
     63         int v = edge[i].v;
     64         if(!vis[v]) {
     65             vis[v] = true;
     66             if(cnt[v] < maxn[v]) {
     67                 love[v][++cnt[v]] = u;
     68                 return true;
     69             }
     70             for(int j = 1; j <= cnt[v]; ++j) {
     71                 if(dfs(love[v][j])) {
     72                     love[v][j] = u;
     73                     return true;
     74                 }
     75             }
     76         }
     77     }
     78     return false;
     79 }
     80 
     81 bool solve() {
     82     rep1(i, m) cnt[i] = 0;
     83     rep1(i, n) {
     84         rep1(j, m) vis[j] = false;
     85         if(!dfs(i)) return false;
     86     }
     87     return true;
     88 }
     89 
     90 int main() {
     91     while(cin >> n >> m) {
     92         num = 0;
     93         rep1(i, n) head[i] = -1;
     94         int x;
     95         rep1(i, n) rep1(j, m) {
     96             read(x);
     97             if(x == 1) add(i, j);
     98         }
     99         rep1(i, m) cin >> maxn[i];
    100         if(solve()) cout << "YES
    ";
    101         else cout << "NO
    ";
    102     }
    103     return 0;
    104 }
    View Code

     // hdu 3081 二分+并查集+最大流

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<queue>
      5 #define INF 0x3f3f3f3f
      6 using namespace std;
      7 const int MAXN = 205;
      8 const int MAXE = 40005+5;
      9 
     10 int num;
     11 int head[MAXN];
     12 struct node {
     13     int v, flow;
     14     int next;
     15 } edge[MAXE];
     16 
     17 inline void add(int x, int y, int w) {
     18     edge[num].v = y;
     19     edge[num].flow = w;
     20     edge[num].next = head[x];
     21     head[x] = num++;
     22 }
     23 
     24 int n, m, f;
     25 int fa[MAXN];
     26 bool vis[MAXN][MAXN], vis2[MAXN][MAXN];
     27 
     28 inline int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
     29 
     30 void init() {
     31     memset(vis, false, sizeof(vis));
     32     memset(vis2, false, sizeof(vis2));
     33     for(int i = 1; i <= n; ++i) fa[i] = i;
     34     int x, y;
     35     for(int i = 0; i != m; ++i) {
     36         scanf("%d%d", &x, &y);
     37         vis[x][y] = vis2[x][y] = true;
     38     }
     39     for(int i = 0; i != f; ++i) {
     40         scanf("%d%d", &x, &y);
     41         int xf = find(x), yf = find(y);
     42         fa[xf] = yf;
     43     }
     44 }
     45 
     46 int S, T;
     47 int dis[MAXN], cur[MAXN];
     48 
     49 void draw(int f) {
     50     S = 0; T = n*2+1;
     51     num = 0;
     52     for(int i = 0; i <= T; ++i) head[i] = -1;
     53     for(int i = 1; i <= n; ++i) {
     54         for(int j = 1; j <= n; ++j) {
     55             vis[i][j] = vis2[i][j];
     56         }
     57     }
     58     
     59     for(int i = 1; i <= n; ++i) {
     60         add(S, i, f);
     61         add(i, S, 0);
     62         add(n+i, T, f);
     63         add(T, n+i, 0);
     64     }
     65     for(int i = 1; i <= n; ++i) {
     66         for(int j = 1; j <= n; ++j) {
     67             if(vis[i][j]) {
     68                 add(i, n+j, 1);
     69                 add(n+j, i, 0);
     70             }
     71         }
     72     }
     73     for(int i = 1; i <= n; ++i) {
     74         for(int j = 1; j <= n; ++j) {
     75             if(find(i) == find(j)) {
     76                 for(int k = 1; k <= n; ++k) {
     77                     if(vis[i][k] && !vis[j][k]) {
     78                         add(j, n+k, 1);
     79                         add(n+k, j, 0);
     80                         vis[j][k] = 1;
     81                     }
     82                 }
     83             }
     84         }
     85     }
     86 }
     87 
     88 bool bfs() {
     89     for(int i = 0; i <= T; ++i) dis[i] = 0;
     90     dis[S] = 1;
     91     queue<int> q;
     92     q.push(S);
     93     while(!q.empty()) {
     94         int u = q.front();
     95         q.pop();
     96         for(int i = head[u]; i != -1; i = edge[i].next) {
     97             int v = edge[i].v;
     98             if(!dis[v] && edge[i].flow) {
     99                 dis[v] = dis[u] + 1;
    100                 q.push(v);
    101             }
    102         }
    103     }
    104     return dis[T];
    105 }
    106 
    107 int dfs(int u, int f) {
    108     if(u == T || (!f)) return f;
    109     int flow = 0;
    110     for(int& i = cur[u]; i != -1; i = edge[i].next) {
    111         int v = edge[i].v;
    112         if(dis[v] == dis[u] + 1) {
    113             int di = dfs(v, min(f, edge[i].flow));
    114             if(di) {
    115                 f -= di;
    116                 flow += di;
    117                 edge[i].flow -= di;
    118                 edge[i^1].flow += di;
    119                 if(!f) break;
    120             }
    121         }
    122     }
    123     if(!flow) dis[u] = -1;
    124     return flow;
    125 }
    126 
    127 int Dinic(int k) {
    128     draw(k);
    129     int ans = 0;
    130     while(bfs()) {
    131         for(int i = 0; i <= T; ++i) cur[i] = head[i];
    132         ans += dfs(S, INF);
    133     }
    134     return ans == n*k;
    135 }
    136 
    137 int main() {
    138     int qaq;
    139     scanf("%d", &qaq);
    140     while(qaq--) {
    141         scanf("%d%d%d", &n, &m, &f);
    142         init();
    143         int l = 0, r = n;
    144         int ans = 0;
    145         while(l <= r) {
    146             int mid = (l+r)>>1;
    147             if(Dinic(mid)) l = mid + 1, ans = mid;
    148             else r = mid - 1;
    149         }
    150         printf("%d
    ", ans);
    151     }
    152     return 0;
    153 }
    View Code

    // hdu 3416 最短路+最大流

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<stack>
      5 #define INF 0x3f3f3f3f
      6 using namespace std;
      7 const int MAXN = 1088+5;
      8 const int MAXE = 800088+5;
      9 
     10 int num1;
     11 int head1[MAXN];
     12 struct node1 {
     13     int v, w;
     14     int next;
     15 } e1[MAXE];
     16 
     17 inline void add1(int x, int y, int w) {
     18     e1[num1].v = y;
     19     e1[num1].w = w;
     20     e1[num1].next = head1[x];
     21     head1[x] = num1++;
     22 }
     23 //---------------------------
     24 int num2;
     25 int head2[MAXN];
     26 struct node2 {
     27     int v, w;
     28     int next;
     29 } e2[MAXE];
     30 
     31 inline void add2(int x, int y, int w) {
     32     e2[num2].v = y;
     33     e2[num2].w = w;
     34     e2[num2].next = head2[x];
     35     head2[x] = num2++;
     36 }
     37 //-------------------------------
     38 int num;
     39 int head[MAXN];
     40 struct node {
     41     int v, flow;
     42     int next;
     43 } edge[MAXE];
     44 
     45 inline void add(int x, int y, int w) {
     46     edge[num].v = y;
     47     edge[num].flow = w;
     48     edge[num].next = head[x];
     49     head[x] = num++;
     50 }
     51 //-------------------------------------
     52 int n, m;
     53 int S, T;
     54 int d;
     55 int dis2[MAXN];
     56 bool vis[MAXN];
     57 int d1[MAXN], d2[MAXN];
     58 
     59 void SPFA1(int s) {
     60     for(int i = 1; i <= n; ++i) dis2[i] = INF, vis[i] = false;
     61     dis2[s] = 0;
     62     vis[s] = 1;
     63     stack<int> q;
     64     q.push(s);
     65     while(!q.empty()) {
     66         int u = q.top();
     67         q.pop();
     68         vis[u] = false;
     69         for(int i = head1[u]; i != -1; i = e1[i].next) {
     70             int v = e1[i].v;
     71             if(dis2[v] > dis2[u] + e1[i].w) {
     72                 dis2[v] = dis2[u] + e1[i].w;
     73                 if(!vis[v]) {
     74                     vis[v] = true;
     75                     q.push(v);
     76                 }
     77             }
     78         }
     79     }
     80 }
     81 
     82 void SPFA2(int s) {
     83     for(int i = 1; i <= n; ++i) dis2[i] = INF, vis[i] = false;
     84     dis2[s] = 0;
     85     vis[s] = 1;
     86     stack<int> q;
     87     q.push(s);
     88     while(!q.empty()) {
     89         int u = q.top();
     90         q.pop();
     91         vis[u] = false;
     92         for(int i = head2[u]; i != -1; i = e2[i].next) {
     93             int v = e2[i].v;
     94             if(dis2[v] > dis2[u] + e2[i].w) {
     95                 dis2[v] = dis2[u] + e2[i].w;
     96                 if(!vis[v]) {
     97                     vis[v] = true;
     98                     q.push(v);
     99                 }
    100             }
    101         }
    102     }
    103 }
    104 
    105 void init() {
    106     num1 = 0;
    107     for(int i = 1; i <= n; ++i) head1[i] = -1;
    108     int s, e, w;
    109     for(int i = 0; i != m; ++i) {
    110         scanf("%d%d%d", &s, &e, &w);
    111         add1(s, e, w);
    112     }
    113     scanf("%d%d", &S, &T);    
    114 }
    115 
    116 void draw() {
    117     memcpy(d1, dis2, sizeof(dis2));
    118     num2 = 0;
    119     for(int i = 1; i <= n; ++i) head2[i] = -1;
    120     for(int u = 1; u <= n; ++u) {
    121         for(int i = head1[u]; i != -1; i = e1[i].next) {
    122             int v = e1[i].v;
    123             add2(v, u, e1[i].w);
    124         }
    125     }
    126     SPFA2(T);
    127     memcpy(d2, dis2, sizeof(dis2));
    128     num = 0;
    129     for(int i = 1; i <= n; ++i) head[i] = -1;
    130     for(int u = 1; u <= n; ++u) {
    131         for(int i = head1[u]; i != -1; i = e1[i].next) {
    132             int v = e1[i].v;
    133             if(d1[u] + e1[i].w + d2[v] == d) {
    134                 add(u, v, 1);
    135                 add(v, u, 0); 
    136             }
    137         }
    138     }
    139 }
    140 
    141 int dis[MAXN], cur[MAXN];
    142 int q[MAXN], ll, rr;
    143 
    144 bool bfs() {
    145     for(int i = 1; i <= n; ++i) dis[i] = 0;
    146     dis[S] = 1;
    147     q[1] = S;
    148     ll = rr = 1;
    149     while(ll <= rr) {
    150         int u = q[ll++];
    151         for(int i = head[u]; i != -1; i = edge[i].next) {
    152             int v = edge[i].v;
    153             if(!dis[v] && edge[i].flow) {
    154                 dis[v] = dis[u] + 1;
    155                 q[++rr] = v;
    156             }
    157         }
    158     }
    159     return dis[T];
    160 }
    161 
    162 int dfs(int u, int f) {
    163     if(u == T || (!f)) return f;
    164     int flow = 0;
    165     for(int& i = cur[u]; i != -1; i = edge[i].next) {
    166         int v = edge[i].v;
    167         if(dis[v] == dis[u] + 1) {
    168             int di = dfs(v, min(f, edge[i].flow));
    169             if(di) {
    170                 f -= di;
    171                 flow += di;
    172                 edge[i].flow -= di;
    173                 edge[i^1].flow += di;
    174                 if(!f) break;
    175             }
    176         }
    177     }
    178     if(!flow) dis[u] = -1;
    179     return flow;
    180 }
    181 
    182 int Dinic() {
    183     int ans = 0;
    184     while(bfs()) {
    185         for(int i = 1; i <= n; ++i) cur[i] = head[i];
    186         ans += dfs(S, INF);
    187     }
    188     return ans;
    189 }
    190 
    191 int main() {
    192     int qaq;
    193     scanf("%d", &qaq);
    194     while(qaq--) {
    195         scanf("%d%d", &n, &m);
    196         init();
    197         SPFA1(S);
    198         if(dis2[T] != INF) d = dis2[T];
    199         else {
    200             printf("0
    ");
    201             continue;
    202         }
    203         draw();
    204         printf("%d
    ", Dinic());
    205     }
    206     return 0;
    207 }
    View Code
  • 相关阅读:
    PHP install perl module
    PHP 静态页
    PHP对类的操作
    PHP Mysql操作。
    2020.7.16
    2020.7.19
    2020.7.14
    2020.7.12
    2020.7.17
    2020.7.10
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11824015.html
Copyright © 2020-2023  润新知