题目描述
A 和 B 进行石头剪刀布游戏,共进行 n 个回合,其中 A 出 a 1 a_1 a1 次石头, a 2 a_2 a2 次剪刀, a 3 a_3 a3 次布,B 出 b 1 b_1 b1 次石头, b 2 b_2 b2 次剪刀, b 3 b_3 b3 次布,问 A 最多获胜的次数和最少获胜的次数。
最大流做法:
min:
You can link the source to A’s options (2-rock, 3-scissors, 4-paper) with their respectives capacities ( a 1 a_1 a1, a 2 a_2 a2, a 3 a_3 a3) and the sink to Bob’s ones (5-rock, 6-scissors, 7-paper) with capacities ( b 1 b_1 b1, b 2 b_2 b2, b 3 b_3 b3). Then link the options that make A not win (draw or lose) with infinite capacity and just calculate the max flow in that network. The edges will be: (source, 2), (source, 3), (source, 4), (2, 5), (2, 7), (3, 6), (3, 5), (4, 7), (4, 6), (5, sink), (6, sink), (7, sink). So the minimun number of rounds A can win will be (n - max_flow(from 1 to 8)).
max:
Similarly, link the options that make A win with infinite capacity and just calculate the max flow in that network, So the maximum number of rounds A can win will be max_flow(from 1 to 8).
做法2 (math):
max:
Consider the option A will win : a 1 a_1 a1 -> b 2 b_2 b2, a 2 a_2 a2 -> b 3 b_3 b3, a 3 a_3 a3 -> b 1 b_1 b1,so the answer is : min( a 1 a_1 a1, b 2 b_2 b2) + min( a 2 a_2 a2, b 3 b_3 b3) + min( a 3 a_3 a3, b 1 b_1 b1).
min:
The answer is : m a x ( 0 , a 1 − b 1 − b 3 , a 2 − b 2 − b 1 , a 3 − b 3 − b 2 ) max({0, a_1 - b_1 - b_3, a_2 - b_2 - b_1, a_3 - b_3 - b_2}) max(0,a1−b1−b3,a2−b2−b1,a3−b3−b2).
Proof:
Obviously, this is a lower bound, but can we reach it? Just to prove it :
- ( a 1 − b 1 − b 3 a_1-b_1-b_3 a1−b1−b3) + ( a 2 − b 1 − b 2 a_2 - b_1 - b_2 a2−b1−b2) + ( a 3 − b 2 − b 3 a_3 - b_2 - b_3 a3−b2−b3) = − n -n −n.
- B 1 = a 1 − b 1 − b 3 > = − n B_1 = a_1-b_1-b_3 >= -n B1=a1−b1−b3>=−n
- B 2 = a 2 − b 1 − b 2 > = − n B_2=a_2-b_1-b_2 >= -n B2=a2−b1−b2>=−n
- B 3 = a 3 − b 2 − b 3 > = − n B_3=a_3-b_2-b_3 >= -n B3=a3−b2−b3>=−n
- If two of ( B 1 , B 2 , B 3 B_1,B_2,B_3 B1,B2,B3) are greater than 0, then the other is less than -n, but this is impossible, all three are either less than or equal to 0, or only one is greater than 0. I.If B 1 < = 0 B_1<=0 B1<=0, B 2 < = 0 B_2<=0 B2<=0 and B 3 < = 0 B3<=0 B3<=0,this is correct. II.Only one is greater than 0.For example, a 1 − b 1 − b 3 > 0 a_1-b_1-b_3>0 a1−b1−b3>0, and after removing the game that Alice won, a 1 = b 1 + b 3 a_1=b_1+b_3 a1=b1+b3, so that b 1 b_1 b1 and b 3 b_3 b3 consume a 1 a_1 a1. At this time, b 1 b_1 b1=0, b 3 b_3 b3=0, a 1 a_1 a1=0, obviously a 2 a_2 a2 , a 3 a_3 a3 can’t win b 2 b_2 b2.
最大流 AC Codes:
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 15, INF = 0x3f3f3f3f;
int n;
int g[N][N], pre[N], flow[N], d[N];
int Edmonds_Karp(int s, int t) {
int max_flow = 0;
while (1) {
memset(pre, -1, sizeof pre);
memset(d, 0x3f, sizeof d);
flow[s] = INF, d[s] = 0;
queue<int> Q;
Q.push(s);
while (!Q.empty()) {
int u = Q.front();
Q.pop();
if (u == t) break;
for (int v = 1; v <= 8; v++) {
if (v != s && g[u][v] > 0 && d[v] == INF) {
pre[v] = u, d[v] = d[u] + 1, flow[v] = min(flow[u], g[u][v]);
Q.push(v);
}
}
}
if (d[t] == INF) break;
max_flow += flow[t];
int cur = t;
while (cur != s) {
int fa = pre[cur];
g[fa][cur] -= flow[t], g[cur][fa] += flow[t];
cur = fa;
}
}
return max_flow;
}
int main() {
cin >> n;
int a1, a2, a3, b1, b2, b3;
cin >> a1 >> a2 >> a3 >> b1 >> b2 >> b3;
g[1][2] = a1, g[1][3] = a2, g[1][4] = a3, g[5][8] = b1, g[6][8] = b2, g[7][8] = b3;
g[2][5] = g[2][7] = g[3][6] = g[3][5] = g[4][7] = g[4][6] = INF;
cout << n - Edmonds_Karp(1, 8) << ' ';
memset(g, 0, sizeof g);
g[1][2] = a1, g[1][3] = a2, g[1][4] = a3, g[5][8] = b1, g[6][8] = b2, g[7][8] = b3;
g[2][6] = g[3][7] = g[4][5] = INF;
cout << Edmonds_Karp(1, 8) << '\n';
return 0;
}
做法2 AC Codes:
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <cstring>
using namespace std;
int main() {
cin >> n;
int a1, a2, a3, b1, b2, b3;
cin >> a1 >> a2 >> a3 >> b1 >> b2 >> b3;
cout << max({0, a1 - b1 - b3, a2 - b2 - b1, a3 - b3 - b2}) << ' ';
cout << min(a1, b2) + min(a2, b3) + min(a3, b1) << '\n';
return 0;
}