Description
Input
Output
YES" (without quotes) if it's possible for the team 1 to score at least as much wins as any other team of its division, and "
NO" (without quotes) otherwise.
题目大意:某小组有n支队伍要比赛,现在每支队伍已经赢了w[i]场,每支队伍还要比r[i]场,每场分同小组竞赛和不同小组竞赛,然后给一个矩阵(小组内竞赛),i行j列为队伍i与队伍j还要比多少场比赛,问队伍1有没有在小组内拿最高分(假设赢一场得一分)的可能性(可以跟其他队伍同分)
思路:首先,队伍1要赢,最好是要1把所有比赛都赢了(包括小组内和小组外),然后其他小组的分都要尽量低,所以其他队伍都要输掉小组外的比赛。那么设小组1能赢max_score场。那么怎么分配其他比赛的获胜方呢?这里就要用到网络流建图。从源点到每支队伍间的比赛连一条边,容量为该竞赛的场数,然后该竞赛再向该比赛的两支队伍连一条容量为无穷大的边(你喜欢容量为场数也可以o(╯□╰)o)。然后,每支队伍(不包括1),连一条容量为max_score - w[i]的边到汇点(不能让这支队伍赢太多啊会超过1的o(╯□╰)o)。如果最大流等于小组内比赛数,那就是YES(分配了所有比赛的结果,还是没人能超过max_score,有可行解),否则输出NO。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 7 const int INF = 0x7fff7fff; 8 const int MAX = 25; 9 const int MAXN = MAX * MAX; 10 const int MAXE = 10 * MAXN; 11 12 struct Dinic { 13 int head[MAXN], cur[MAXN], dis[MAXN]; 14 int to[MAXE], next[MAXE], cap[MAXE], flow[MAXE]; 15 int n, st, ed, ecnt; 16 17 void init() { 18 memset(head, 0, sizeof(head)); 19 ecnt = 2; 20 } 21 22 void add_edge(int u, int v, int c) { 23 to[ecnt] = v; cap[ecnt] = c; flow[ecnt] = 0; next[ecnt] = head[u]; head[u] = ecnt++; 24 to[ecnt] = u; cap[ecnt] = 0; flow[ecnt] = 0; next[ecnt] = head[v]; head[v] = ecnt++; 25 } 26 27 bool bfs() { 28 memset(dis, 0, sizeof(dis)); 29 queue<int> que; que.push(st); 30 dis[st] = 1; 31 while(!que.empty()) { 32 int u = que.front(); que.pop(); 33 for(int p = head[u]; p; p = next[p]) { 34 int v = to[p]; 35 if(!dis[v] && cap[p] > flow[p]) { 36 dis[v] = dis[u] + 1; 37 que.push(v); 38 if(v == ed) return true; 39 } 40 } 41 } 42 return dis[ed]; 43 } 44 45 int dfs(int u, int a) { 46 if(u == ed || a == 0) return a; 47 int outflow = 0, f; 48 for(int &p = cur[u]; p; p = next[p]) { 49 int v = to[p]; 50 if(dis[u] + 1 == dis[v] && (f = dfs(v, min(a, cap[p] - flow[p]))) > 0) { 51 flow[p] += f; 52 flow[p ^ 1] -= f; 53 outflow += f; 54 a -= f; 55 if(a == 0) break; 56 } 57 } 58 return outflow; 59 } 60 61 int Maxflow(int ss, int tt, int nn) { 62 st = ss; ed = tt; n = nn; 63 int ans = 0; 64 while(bfs()) { 65 for(int i = 0; i <= n; ++i) cur[i] = head[i]; 66 ans += dfs(st, INF); 67 } 68 return ans; 69 } 70 } G; 71 72 int r[MAX], w[MAX]; 73 int n; 74 75 int main() { 76 scanf("%d", &n); 77 for(int i = 1; i <= n; ++i) scanf("%d", &w[i]); 78 for(int i = 1; i <= n; ++i) scanf("%d", &r[i]); 79 int max_score = w[1] + r[1], node_cnt = n, game_cnt = 0; 80 for(int i = 2; i <= n; ++i) 81 if(max_score < w[i]) {puts("NO"); return 0;} 82 G.init(); 83 int ss = 1; 84 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) { 85 int x; scanf("%d", &x); 86 if(i == 1 || i >= j || x == 0) continue; 87 game_cnt += x; 88 G.add_edge(ss, ++node_cnt, x); 89 G.add_edge(node_cnt, i, INF); 90 G.add_edge(node_cnt, j, INF); 91 } 92 int tt = ++node_cnt; 93 for(int i = 2; i <= n; ++i) G.add_edge(i, tt, max_score - w[i]); 94 if(G.Maxflow(ss, tt, node_cnt) == game_cnt) puts("YES"); 95 else puts("NO"); 96 }