L3-3 勝利者集合(天梯賽)
阿新 • • 發佈:2022-04-04
這個題知道是最大流 但是比賽的時候就是不知道怎麼建圖
#include <bits/stdc++.h> using namespace std; const int N = 1500, M = 10010, INF = 1e9; int n, m, S, T; struct Edge { int to, nxt, flow; }line[M]; int fist[N], idx, d[N], cur[N]; void add(int x, int y, int z) { line[idx] = {y, fist[x], z}; fist[x] = idx ++; line[idx] = {x, fist[y], 0}; fist[y] = idx ++; } bool bfs() { queue<int> q; memset(d, -1, sizeof d); q.push(S), d[S] = 0, cur[S] = fist[S]; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = fist[u]; i != -1; i = line[i].nxt) { int v = line[i].to; if(d[v] == -1 && line[i].flow) { d[v] = d[u] + 1; cur[v] = fist[v]; if(v == T) return 1; q.push(v); } } } return 0; } int find(int u, int limit) { if(u == T) return limit; int flow = 0; for(int i = cur[u]; i != -1 && flow < limit; i = line[i].nxt) { cur[u] = i; int v = line[i].to; if(d[v] == d[u] + 1 && line[i].flow) { int t = find(v, min(line[i].flow, limit - flow)); if(!t) d[v] = -1; line[i].flow -= t; line[i ^ 1].flow += t; flow += t; } } return flow; } int dinic() { int res = 0, flow; while(bfs()) while(flow = find(S, INF)) res += flow; return res; } int main() { ios::sync_with_stdio(0); cin.tie(nullptr); cout.tie(nullptr); cin >> n >> m; vector<vector<int>> g(n, vector<int>(n, 0)); for(int i = 0; i < m; ++ i) { int u, v; cin >> u >> v; u --, v --; g[u][v] = 1, g[v][u] = -1; } S = n + (n - 2) * (n - 1) / 2; T = S + 1; int flag = 0; for(int i = 0; i < n; ++ i) { int win = n - 1; for(int j = 0; j < n; ++ j) if(g[i][j] == -1) win --; idx = 0; memset(fist, -1, sizeof fist); int cur = n; for(int j = 0; j < n; ++ j) { if(j == i) continue; for(int k = j + 1; k < n; ++ k) { if(k == i) continue; add(S, cur, 1); if(g[j][k] == 0) { add(cur, j, 1); add(cur, k, 1); } if(g[j][k] == 1) add(cur, j, 1); if(g[j][k] == -1) add(cur, k, 1); cur ++; } } bool ok = true; for(int j = 0; j < n; ++ j) { if(win - 1 - (g[j][i] > 0) < 0) { ok = false; break; } if(j != i) add(j, T, win - 1 - (g[j][i] > 0)); } if(!ok) continue; if(dinic() == (n - 1) * (n - 2) / 2) { if(flag) cout << ' '; cout << i + 1; flag = 1; } } cout << '\n'; return 0; }