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 }