題意:
電腦公司生產電腦有N個機器,每個機器單位時間產量為Qi。 電腦由P個部件組成,每個機器工作時只能把有某些部件的半成品電腦(或什么都沒有的空電腦)變成有另一些部件的半成品電腦或完整電腦(也可能移除某些部件)。求電腦公司的單位時間最大產量,以及哪些機器有協作關系,即一台機器把它的產品交給哪些機器加工。
Sample input
3 4
15 0 0 0 0 1 0
10 0 0 0 0 1 1
30 0 1 2 1 1 1
3 0 2 1 1 1 1
Sample output
25 2
1 3 15
2 3 10
輸入:電腦由3個部件組成,共有4台機器,1號機器產量15, 能給空電腦加上2號部件,2號 機器能給空電腦加上2號部件和3號部件, 3號機器能把有1個2號部件和3號部件有無均可的電腦變成成品(每種部件各有一個)
輸出:單位時間最大產量25,有兩台機器有協作關系,
1號機器單位時間內要將15個電腦給3號機器加工
2號機器單位時間內要將10個電腦給3號機器加工
思路:
網絡流模型:
1) 添加一個原點S,S提供最初的原料 00000...
2) 添加一個匯點T, T接受最終的產品 11111...
3) 將每個機器拆成兩個點: 編號為i的接收節點,和編號為i+n的產出節點(n是機器數目),前者用於接收原料,后者用於提供加工后的半成品或成品。這兩個點之間要連一條邊,容量為單位時間產量Qi
4) S 連邊到所有接收 "0000..." 或 "若干個0及若干個2" 的機器,容量為無窮大
5) 產出節點連邊到能接受其產品的接收節點,容量無窮大
6) 能產出成品的節點,連邊到T,容量無窮大。
7) 求S到T的最大流
實現:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 const int INF = 0x3f3f3f3f; 8 9 int g[105][15], p, n, q[55]; 10 int G[105][105], G_copy[105][105], layer[105], vis[105]; 11 12 struct node 13 { 14 int x, y, c; 15 }; 16 17 bool countLayer(int s, int e) 18 { 19 layer[s] = 0; 20 queue<int> q; 21 q.push(s); 22 memset(vis, 0, sizeof(vis)); 23 vis[s] = true; 24 while (!q.empty()) 25 { 26 int tmp = q.front(); 27 q.pop(); 28 for (int i = 1; i <= e; i++) 29 { 30 if (G[tmp][i] && !vis[i]) 31 { 32 layer[i] = layer[tmp] + 1; 33 if (i == e) 34 { 35 return true; 36 } 37 vis[i] = true; 38 q.push(i); 39 } 40 } 41 } 42 return false; 43 } 44 45 int dinic(int s, int e) 46 { 47 int flow = 0; 48 deque<int> q; 49 while (countLayer(s, e)) 50 { 51 memset(vis, 0, sizeof(vis)); 52 vis[s] = true; 53 q.push_back(s); 54 while (!q.empty()) 55 { 56 int tmp = q.back(); 57 if (tmp == e) 58 { 59 int minn = INF; 60 int min_index = 0; 61 for (int i = 1; i < q.size(); i++) 62 { 63 if (G[q[i - 1]][q[i]] && G[q[i - 1]][q[i]] < minn) 64 { 65 minn = G[q[i - 1]][q[i]]; 66 min_index = i - 1; 67 } 68 } 69 for (int i = 1; i < q.size(); i++) 70 { 71 G[q[i - 1]][q[i]] -= minn; 72 G[q[i]][q[i - 1]] += minn; 73 } 74 while (q.size() && q.back() != min_index) 75 { 76 vis[q.back()] = false; 77 q.pop_back(); 78 } 79 flow += minn; 80 } 81 else 82 { 83 bool flag = false; 84 for (int i = 1; i <= e; i++) 85 { 86 if (G[tmp][i] && !vis[i] && layer[i] == layer[tmp] + 1) 87 { 88 vis[i] = true; 89 q.push_back(i); 90 flag = true; 91 break; 92 } 93 } 94 if (!flag && q.size()) 95 { 96 q.pop_back(); 97 } 98 } 99 } 100 } 101 return flow; 102 } 103 104 int main() 105 { 106 while (cin >> p >> n) 107 { 108 for (int i = 0; i < n; i++) 109 { 110 cin >> q[i]; 111 for (int j = 0; j < p; j++) 112 { 113 cin >> g[i][j]; 114 } 115 for (int j = 0; j < p; j++) 116 { 117 cin >> g[i + n][j]; 118 } 119 } 120 memset(G, 0, sizeof(G)); 121 for (int i = 2; i < n + 2; i++) 122 { 123 G[i][i + n] = q[i - 2]; 124 } 125 for (int i = 2; i < n + 2; i++) 126 { 127 bool flag = true; 128 for (int j = 0; j < p; j++) 129 { 130 if (g[i - 2][j] != 0 && g[i - 2][j] != 2) 131 { 132 flag = false; 133 break; 134 } 135 } 136 if (flag) 137 { 138 G[1][i] = INF; 139 } 140 } 141 for (int i = n + 2; i < 2 * n + 2; i++) 142 { 143 bool flag = true; 144 for (int j = 0; j < p; j++) 145 { 146 if (g[i - 2][j] != 1) 147 { 148 flag = false; 149 break; 150 } 151 } 152 if (flag) 153 { 154 G[i][2 * n + 2] = INF; 155 } 156 } 157 for (int i = n + 2; i < 2 * n + 2; i++) 158 { 159 for (int j = 2; j < n + 2; j++) 160 { 161 bool flag = true; 162 for (int k = 0; k < p; k++) 163 { 164 if (!(g[i - 2][k] == g[j - 2][k] || g[j - 2][k] == 2)) 165 { 166 flag = false; 167 break; 168 } 169 } 170 if (flag) 171 { 172 G[i][j] = INF; 173 } 174 } 175 } 176 for (int i = 1; i <= 2 * n + 2; i++) 177 { 178 for (int j = 1; j <= 2 * n + 2; j++) 179 { 180 G_copy[i][j] = G[i][j]; 181 } 182 } 183 cout << dinic(1, 2 * n + 2) << " "; 184 int cnt = 0; 185 vector<node> v; 186 for (int i = n + 2; i < 2 * n + 2; i++) 187 { 188 for (int j = 2; j < n + 2; j++) 189 { 190 if (i - n != j && G[i][j] != G_copy[i][j]) 191 { 192 cnt++; 193 node tmp; 194 tmp.x = i - n - 1; 195 tmp.y = j - 1; 196 tmp.c = G_copy[i][j] - G[i][j]; 197 v.push_back(tmp); 198 } 199 } 200 } 201 cout << cnt << endl; 202 for (int i = 0; i < v.size(); i++) 203 { 204 cout << v[i].x << " " << v[i].y << " " << v[i].c << endl; 205 } 206 } 207 return 0; 208 }