SGU326(最大流)

来源:互联网 发布:淘宝女装春装2015新款上市 编辑:程序博客网 时间:2024/06/07 17:42
同样,所有和球队 1 相关的比赛全让球队 1 赢,如果此
时仍有某支球队胜利的场数大于球队 1,则已经不可能满足要求。按如下方法建
图:所有小组内的比赛 i(不包括与球队 1 相关的比赛)作为一个点并加边(s, i,
num[i]),每支球队(不包括球队 1)作为一个点并加边(j, t, wins[1]-wins[i]),每场
比赛向与其关联的两支球队 u, v 连边(i, u, ∞), (i, v, ∞)。至于其他球队小组间的

比赛,直接让他们输掉就好,不用管。若最大流等于∑num[i]则可以满足要求

#include<cstdio>#include<vector>#include<queue>#include<cstring>using namespace std;////////////////////////×î´óÁ÷¿ªÊ¼//////////////////////////////////////typedef int cap_type;#define MAX_V 500 + 30 + 16// ÓÃÓÚ±íʾ±ßµÄ½á¹¹Ì壨Öյ㡢ÈÝÁ¿¡¢·´Ïò±ß£©struct edge{int to, rev;cap_type cap;edge(int to, cap_type cap, int rev) : to(to), cap(cap), rev(rev){}};vector <edge> G[MAX_V];   // ͼµÄÁÚ½Ó±í±íʾint level[MAX_V];      // ¶¥µãµ½Ô´µãµÄ¾àÀë±êºÅint iter[MAX_V];       // µ±Ç°»¡£¬ÔÚÆä֮ǰµÄ±ßÒѾ­Ã»ÓÐÓÃÁË// ÏòͼÖмÓÈëÒ»Ìõ´Ófromµ½toµÄÈÝÁ¿ÎªcapµÄ±ßvoid add_edge(int from, int to, int cap){G[from].push_back(edge(to, cap, G[to].size()));G[to].push_back(edge(from, 0, G[from].size() - 1));}// ͨ¹ýBFS¼ÆËã´ÓÔ´µã³ö·¢µÄ¾àÀë±êºÅvoid bfs(int s){memset(level, -1, sizeof(level));queue<int> que;level[s] = 0;que.push(s);while (!que.empty()){int v = que.front();que.pop();for (int i = 0; i < G[v].size(); ++i){edge &e = G[v][i];if (e.cap > 0 && level[e.to] < 0){level[e.to] = level[v] + 1;que.push(e.to);}}}}// ͨ¹ýDFSÑ°ÕÒÔö¹ã·cap_type dfs(int v, int t, cap_type f){if (v == t){return f;}for (int &i = iter[v]; i < G[v].size(); ++i){edge &e = G[v][i];if (e.cap > 0 && level[v] < level[e.to]){cap_type d = dfs(e.to, t, min(f, e.cap));if (d > 0){e.cap -= d;G[e.to][e.rev].cap += d;return d;}}}return 0;}// Çó½â´Ósµ½tµÄ×î´óÁ÷cap_type max_flow(int s, int t){cap_type flow = 0;for (;;){bfs(s);if (level[t] < 0){return flow;}memset(iter, 0, sizeof(iter));cap_type f;while ((f = dfs(s, t, 0x3f3f3f3f3f3f3f3f)) > 0){flow += f;}}}const int maxn = 25;///////////////////////////////×î´óÁ÷½áÊø/////////////////////////////////////int w[maxn],r[maxn];int bmap[maxn][maxn];int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&w[i]);    for(int i=1;i<=n;i++) scanf("%d",&r[i]);    w[1] += r[1]; r[1] = 0; int tot = 0;    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&bmap[i][j]);    int f = 1; int s = 0,t = 1;    for(int i=2;i<=n;i++)if(w[i]>w[1]){ f = 0; break;}    if(f==0){printf("NO\n"); return 0; }    for(int i=2;i<=n;i++)    {        for(int j=i+1;j<=n;j++)        {            if(bmap[i][j]<=0) continue;            add_edge(0,i*20+j,bmap[i][j]); add_edge(i*20+j,i,10000000);            add_edge(20*i+j,j,10000000); tot += bmap[i][j];        }        add_edge(i,t,w[1]-w[i]);    }    int ans = max_flow(s,t);    if(ans==tot) puts("YES");    else puts("NO");    return 0;}/*21 11 10 11 0*/