zoukankan      html  css  js  c++  java
  • HIT 2713 Matrix1

    HIT_2713

        拿走的最大就等同于留下的最少,因此问题就变成了留下最少价值的宝石使得拿走的宝石都不是相邻的。

        先将每个格子按i+j的奇偶性进行黑白染色,然后将S连上所有黑格子,容量为对应格子的价值,再将所有白格子连T,容量也为对应格子的价值,最后将黑格子和相邻的白格子连起来,容量为INF。

        我们期望得到的解是这个图的一个割,其中由S出发能到达的点表示留下的白格子以及拿走的黑格子,能够到达T的点表示留下的黑格子以及拿走的白格子,为了使留下的的格子的价值尽可能少,对原图做最小割即可。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXD 2510
    #define MAXM 15010
    #define INF 0x3f3f3f3f
    int N, M, first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM];
    int SUM, S, T, d[MAXD], q[MAXD], work[MAXD];
    int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
    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, k, x, ni, nj;
        scanf("%d%d", &N, &M);
        S = 0, T = N * M + 1;
        memset(first, -1, sizeof(first[0]) * (T + 1));
        e = 0;
        SUM = 0;
        for(i = 1; i <= N; i ++)
            for(j = 1; j <= M; j ++)
            {
                scanf("%d", &x), SUM += x;
                if(i + j & 1)
                {
                    add(S, (i - 1) * M + j, x), add((i - 1) * M + j, S, 0);
                    for(k = 0; k < 4; k ++)
                    {
                        ni = i + dx[k], nj = j + dy[k];
                        if(ni >= 1 && ni <= N && nj >= 1 && nj <= M)
                            add((i - 1) * M + j, (ni - 1) * M + nj, INF), add((ni - 1) * M + nj, (i - 1) * M + j, 0);
                    }
                }
                else
                    add((i - 1) * M + j, T, x), add(T, (i - 1) * M + 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;
        for(int &i = work[cur]; i != -1; i = next[i])
            if(flow[i] && d[v[i]] == d[cur] + 1)
                if(int 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()
    {
        printf("%d\n", SUM - dinic());
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t --)
        {
            init();
            solve();    
        }
        return 0;    
    }
  • 相关阅读:
    springmvc
    POJ 3683 Priest John's Busiest Day
    POJ 3678 Katu Puzzle
    HDU 1815 Building roads
    CDOJ UESTC 1220 The Battle of Guandu
    HDU 3715 Go Deeper
    HDU 3622 Bomb Game
    POJ 3207 Ikki's Story IV
    POJ 3648 Wedding
    HDU 1814 Peaceful Commission
  • 原文地址:https://www.cnblogs.com/staginner/p/2628347.html
Copyright © 2011-2022 走看看