[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\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", 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\n", u, v);
107             }
108         }
109         printf("\n");
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.\n", ++QAQ);
133         else if(ans == 1) printf("Case #%d: 1 lizard was left behind.\n", ++QAQ);
134         else printf("Case #%d: %d lizards were left behind.\n", ++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("\n");
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\n";
101         else cout << "NO\n";
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\n", 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\n");
201             continue;
202         }
203         draw();
204         printf("%d\n", Dinic());
205     }
206     return 0;
207 }
View Code

 

posted @ 2019-11-10 21:01  pupil337  阅读(191)  评论(0编辑  收藏  举报