Question link: Click the open link
Question:
Given the scores of n teams, output any feasible solution.
There are only one and only one game for any two of the n teams, A and B.
The competition results are divided into four types:
1. A + 3, B + 0
2. A + 0, B + 3
3. A + 2, B + 1
4. A + 1, B + 2
We found that in each result, two teams scored and always three. In four cases, they all split and form three.
Therefore, we can combine any two teams into a single point.
Connect N points to the source point, and the maximum stream is the score of the team.
For two teams
1-> edge with a stream connection ceiling of 3 at point (1, 2)
2-> edge with a stream connection ceiling of 3 at point (1, 2)
Edge with a maximum stream connection limit of 3 from vertex (1, 2) to vertex.
If the stream is full, there is a solution.
The situation between two teams shows the inbound situation (1, 2.
#include <cstdio>#include <algorithm>#include <cstring>#include <queue>using namespace std;typedef long long ll;const int inf = (int)(1e9);const int M = 200 + 2;const int E = M * M * 6 + M * 3;const int N = M * M + M + 5;struct Edge {int from, to, cap, nex;};int head[N], egnum;Edge eg[E];int a[M], n, st, ed;int id[M][M], rid[N], tot;int win[M][M];void add(int u, int v, int cap, int rw = 0) {Edge E = {u, v, cap, head[u]};eg[egnum] = E;head[u] = egnum++;Edge E2 = {v, u, rw, head[v]};eg[egnum] = E2;head[v] = egnum++;}int sign[N];bool bfs(int from, int to) {memset(sign, -1, sizeof sign);sign[from] = 0;queue<int> q;q.push(from);while (!q.empty()) {int u = q.front();q.pop();for (int i = head[u]; i != -1; i = eg[i].nex) {int v = eg[i].to;if (sign[v] == -1 && eg[i].cap) {sign[v] = sign[u] + 1;q.push(v);if (sign[to] != -1)return true;}}}return false;}int Stack[N], top, cur[N];int dicnic(int from, int to) {int ans = 0;while (bfs(from, to)) {memcpy(cur, head, sizeof head);int u = from;top = 0;while (true) {if (u == to) {int flow = inf, loc;for (int i = 0; i < top; ++i)if (flow > eg[Stack[i]].cap) {flow = eg[Stack[i]].cap;loc = i;}for (int i = 0; i < top; ++i) {eg[Stack[i]].cap -= flow;eg[Stack[i] ^ 1].cap += flow;}ans += flow;top = loc;u = eg[Stack[top]].from;}for (int i = cur[u]; i != -1; cur[u] = i = eg[i].nex)if (eg[i].cap && (sign[u] + 1 == sign[eg[i].to]))break;if (cur[u] != -1) {Stack[top++] = cur[u];u = eg[cur[u]].to;} else {if (top == 0)break;sign[u] = -1;u = eg[Stack[--top]].from;}}}return ans;}void init() {memset(head, -1, sizeof head);egnum = 0;}void pu(int x) {if (x == 0) {putchar('<');} else if (x == 1) {putchar('>');} else if (x == 2) {putchar('>');putchar('=');} else {putchar('<');putchar('=');}}void work() {int sum = 0, u, v;for (int i = 0; i < n; ++i) {scanf("%d", &a[i]);sum += a[i];}tot = n;for (int i = 0; i < n; ++i)for (int j = i + 1; j < n; ++j) {id[i][j] = ++tot;rid[tot] = j;}st = ++tot;ed = ++tot;init();for (int i = 0; i < n; ++i)add(st, i, a[i]);for (int i = 0; i < n; ++i)for (int j = i + 1; j < n; ++j) {add(i, id[i][j], 3);add(j, id[i][j], 3);add(id[i][j], ed, 3);}int g = dicnic(st, ed);if (g != sum) {puts("INCORRECT");} else {memset(win, -1, sizeof win);puts("CORRECT");for (int i = 0; i < egnum; ++i) {if (eg[i].from < n && eg[i].to > n && eg[i].to < st) {u = eg[i].from;v = rid[eg[i].to];if (u == v)continue;if (u > v)std::swap(u, v);if (win[u][v] == -1) {if (eg[i].cap == 0) {win[u][v] = 1; //1 = win, 0 = los, 2 = little win, 3 = little los} else if (eg[i].cap == 1) {win[u][v] = 2;} else if (eg[i].cap == 2) {win[u][v] = 3;} else {win[u][v] = 0;}}}}for (int i = 0; i < n; ++i)for (int j = i + 1; j < n; ++j) {printf("%d ", i + 1);pu(win[i][j]);printf(" %d\n", j + 1);}}}int main() {while (~scanf("%d", &n))work();return 0;}
Ural 1736 Chinese hockey network flow + graph Creation