poj 3436 最大流+拆点

今天总算明白了最大流中的拆点的含义,

因为最大流的中两个点u和v,流量的限制记为cap(u,v),

如果一个点u的流量限制为m,那么我们可以把u拆成u1和u2

并且对任意的s,将cap(s,u)换成cap(s,u1),

对任意的e,将cap(u,e)换成cap(u1,e),

最后将cap(u1,u2)置为m,然后套用最大流的通用算法即可

  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <map>
  7 #include <algorithm>
  8 #include <list>
  9 #include <ctime>
 10 #include <set>
 11 #include <string.h>
 12 #include <queue>
 13 using namespace std;
 14 
 15 #define N 1050
 16 int capacity[N][N]; //容量
 17 int capacity2[N][N]; //容量
 18 int flow[N]; //残余流量
 19 int pre[N]; //前趋
 20 #define INT_MAX 10000000;
 21 
 22 int n, m;
 23 queue<int> Q;
 24 
 25 int BFS(int src, int des) {
 26     //初始化
 27     while (!Q.empty()) {
 28         Q.pop();
 29     }
 30     for (int i = 1; i < n + 1; i++) {
 31         pre[i] = -1;
 32     }
 33     pre[src] = 0;
 34     flow[src] = INT_MAX; //初始化源点的流量为无穷大
 35     Q.push(src);
 36     while (!Q.empty()) {
 37         int index = Q.front();
 38         Q.pop();
 39         if (index == des) { //找到了增广路径
 40             break;
 41         }
 42         for (int i = 1; i < n + 1; i++) {
 43             if (i != src && capacity[index][i] > 0 && pre[i] == -1) {
 44                 pre[i] = index;
 45                 //增广路残容流量
 46                 flow[i] = min(capacity[index][i], flow[index]);
 47                 Q.push(i);
 48             }
 49         }
 50     } //while
 51     if (pre[des] == -1) {
 52         return -1; //残留图中不存在增广路径
 53     } else {
 54         return flow[des];
 55     }
 56 }
 57 
 58 int MaxFlow(int src, int des) {
 59     int aug = 0;
 60     int sumflow = 0;
 61     while ((aug = BFS(src, des)) != -1) {
 62         int k = des; //利用前驱寻找路径
 63         while (k != src) {
 64             int last = pre[k];
 65             capacity[last][k] -= aug;
 66             capacity[k][last] += aug;
 67             k = last;
 68         }
 69         sumflow += aug;
 70     }
 71     return sumflow;
 72 }
 73 struct node {
 74     string in, out;
 75     int cap;
 76 };
 77 int checkin(string & a, string& b) {
 78     int sz = a.size();
 79     bool judge = 1;
 80     for (int i = 0; i < sz; i++) {
 81         if (a[i] == '2' || b[i] == '2') {
 82             continue;
 83         } else if (a[i] != b[i]) {
 84             judge = 0;
 85             break;
 86         }
 87     }
 88     if (1 == judge)
 89         return 1;
 90     return 0;
 91 }
 92 int main() {
 93     int kp, kn, cap;
 94     cin >> kp >> kn;
 95     n = 2 * kn + 2;
 96     vector<node> data;
 97     string startstate;
 98     string endstate;
 99     string csta = "0";
100     string cend = "1";
101     for (int i = 0; i < kp; i++) {
102         startstate += csta;
103         endstate += cend;
104     }
105     for (int i = 0; i < kn; i++) {
106         cin >> cap;
107         string t, t2;
108         string statein, stateout;
109         for (int j = 0; j < kp; j++) {
110             cin >> t;
111             statein = statein + t;
112         }
113         t = t2;
114         for (int j = 0; j < kp; j++) {
115             cin >> t;
116             stateout = stateout + t;
117         }
118         node tmp;
119         tmp.cap = cap;
120         tmp.in = statein;
121         tmp.out = stateout;
122         data.push_back(tmp);
123     }
124     for (int i = 0; i < kn; i++) {
125         node tmp = data[i];
126         int u = i + 1;
127         int v = i + 1 + kn;
128         capacity[u][v] = tmp.cap;
129         int judge = checkin(startstate, tmp.in);
130         if (1 == judge) {
131             capacity[0][u] = tmp.cap;
132         }
133         judge = checkin(tmp.out, endstate);
134         if (1 == judge) {
135             capacity[v][n - 1] = tmp.cap;
136         }
137 
138         for (int j = 0; j < kn; j++) {
139             if (j != i) {
140                 node tmp2 = data[j];
141                 int u2 = j + 1;
142                 int v2 = j + 1 + kn;
143                 judge = checkin(tmp2.out, tmp.in);
144                 if (1 == judge) {
145                     capacity[v2][u] = tmp2.cap;
146                 }
147                 judge = checkin(tmp.out, tmp2.in);
148                 if (1 == judge) {
149                     capacity[v][u2] = tmp.cap;
150                 }
151             }
152 
153         }
154     }
155     for (int i = 0; i < N; i++) {
156         for (int j = 0; j < N; j++) {
157             capacity2[i][j] = capacity[i][j];
158         }
159     }
160     int sum = MaxFlow(0, n - 1);
161     cout << sum <<" ";
162     int num=0;
163     for (int i = 0; i < kn; i++) {
164         node tmp = data[i];
165         int u = i + 1;
166         int v = i + 1 + kn;
167         int judge;
168 
169         for (int j = 0; j < kn; j++) {
170             if (j != i) {
171                 node tmp2 = data[j];
172                 int u2 = j + 1;
173                 int v2 = j + 1 + kn;
174                 judge = checkin(tmp.out, tmp2.in);
175                 if (1 == judge) {
176                     int cost = capacity2[v][u2] - capacity[v][u2];
177                     if (cost > 0) {
178                         num++;
179                     }
180                 }
181             }
182         }
183     }
184     cout<<num<<endl;
185 
186     for (int i = 0; i < kn; i++) {
187         node tmp = data[i];
188         int u = i + 1;
189         int v = i + 1 + kn;
190         int judge;
191 
192         for (int j = 0; j < kn; j++) {
193             if (j != i) {
194                 node tmp2 = data[j];
195                 int u2 = j + 1;
196                 int v2 = j + 1 + kn;
197                 judge = checkin(tmp.out, tmp2.in);
198                 if (1 == judge) {
199                     int cost = capacity2[v][u2] - capacity[v][u2];
200                     if (cost > 0) {
201                         cout << i + 1 << " " << j + 1 << " " << cost << endl;
202                     }
203                 }
204             }
205 
206         }
207     }
208     return 0;
209 }
原文地址:https://www.cnblogs.com/kakamilan/p/3055948.html