SGU_326

    这个题目的武大OJ的1124基本是一样的,只不过多了队外的比赛,对于队外的比赛只要让第1组全部赢而其他组全部输即可,剩下的就和WOJ_1124是一样的处理方式了,具体的思路可以参考我的WOJ_1124的题解:http://www.cnblogs.com/staginner/archive/2012/08/07/2626317.html

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 25
#define MAXD 430
#define MAXM 2450
#define INF 0x3f3f3f3f
int N, SUM, score[MAXN], r[MAXN], first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM];
int S, T, d[MAXD], q[MAXD], work[MAXD];
void add(int x, int y, int z)
{
    v[e] = y, flow[e] = z;    
    next[e] = first[x], first[x] = e ++;
}
void init()
{
    int i, j, a;
    for(i = 1; i <= N; i ++)
        scanf("%d", &score[i]);
    for(i = 1; i <= N; i ++)
        scanf("%d", &r[i]);
    score[1] += r[1];
    S = 0, T = N + N * N + 1;
    memset(first, -1, sizeof(first[0]) * (T + 1));
    e = SUM = 0;
    for(i = 1; i <= N; i ++)
        for(j = 1; j <= N; j ++)
        {
            scanf("%d", &a);
            if(a && i < j && i != 1)
            {
                    SUM += a;
                    add(i, i * N + j, a), add(i * N + j, i, 0);
                    add(j, i * N + j, a), add(i * N + j, j, 0);
                    add(i * N + j, T, a), add(T, i * N + j, 0);
            }    
        }
}
int bfs()
{
    int i, j, rear = 0;
    memset(d, -1, sizeof(d[0]) * (T + 1));
    d[S] = 0, q[rear ++] = S;
    for(i = 0; i < rear; i ++)
        for(j = first[q[i]]; j != -1; j = next[j])
            if(flow[j] && d[v[j]] == -1)
            {
                d[v[j]] = d[q[i]] + 1, q[rear ++] = v[j];
                if(v[j] == T)
                    return 1;    
            }
    return 0;
}
int dfs(int cur, int a)
{
    if(cur == T)
        return a;
    int t;
    for(int &i = work[cur]; i != -1; i = next[i])
        if(flow[i] && d[v[i]] == d[cur] + 1)
            if(t = dfs(v[i], std::min(a, flow[i])))
            {
                flow[i] -= t, flow[i ^ 1] += t;
                return t;    
            }    
    return 0;
}
int dinic()
{
    int ans = 0, t;
    while(bfs())
    {
        memcpy(work, first, sizeof(first[0]) * (T + 1));
        while(t = dfs(S, INF))
            ans += t;    
    }    
    return ans;
}
void solve()
{
    int i, j, k;
    for(i = 2; i <= N; i ++)
        if(score[i] > score[1])
        {
            printf("NO\n");
            return ;    
        }
    for(i = 2; i <= N; i ++)
        add(S, i, score[1] - score[i]), add(i, S, 0);
    printf("%s\n", dinic() == SUM ? "YES" : "NO");
}
int main()
{
    while(scanf("%d", &N) == 1)
    {
        init();
        solve();    
    }
    return 0;    
}
posted on 2012-08-07 13:16  Staginner  阅读(299)  评论(0编辑  收藏  举报