HDU 1569(方格取數(2))

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 10005;
const int INF = 0x3f3f3f3f;

int total; //邊的總數量
int s, t; //源點、匯點
int head[MAXN];
int dep[MAXN];
int cur[MAXN];

struct Edge
{
    int u, v, w, next;
}edge[MAXN];

void addEdge(int u, int v, int w)
{
    edge[total] = Edge{ u,v,w,head[u] };
    head[u] = total++;
    edge[total] = Edge{ v,u,0,head[v] };
    head[v] = total++;
}

bool BFS()
{
    memset(dep, 0, sizeof(dep));
    dep[s] = 1;
    queue<int> q;
    q.push(s);
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].v;
            int w = edge[i].w;
            if (w > 0 && dep[v] == 0)
            {
                dep[v] = dep[u] + 1;
                q.push(v);
            }
        }
    }
    return dep[t] != 0;
}

int DFS(int u, int flow)
{
    if (u == t)
        return flow;

    for (int i = cur[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].v;
        int w = edge[i].w;
        if (dep[v] == dep[u] + 1 && w != 0)
        {
            int dis = DFS(v, min(w, flow));
            if (dis > 0)
            {
                edge[i].w -= dis;
                edge[i ^ 1].w += dis;
                return dis;
            }
        }
    }
    return 0;
}

int dinic()
{
    int ans = 0;
    while (BFS())
    {
        for (int i = 0; i <= t; i++)
            cur[i] = head[i];
        while (int d = DFS(s, INF))
            ans += d;
    }
    return ans;
}

int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF)
    {
        memset(head, -1, sizeof(head));
        total = 0;
        s = n * m;
        t = n * m + 1;

        int sum = 0; //所有點的數之和
        int num;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                scanf("%d", &num);
                if ((i + j) % 2)
                {
                    addEdge(s, i * m + j, num);
                    if (i > 0)
                        addEdge(i * m + j, (i - 1) * m + j, INF);
                    if (i < n - 1)
                        addEdge(i * m + j, (i + 1) * m + j, INF);
                    if (j > 0)
                        addEdge(i * m + j, i * m + j - 1, INF);
                    if (j < m - 1)
                        addEdge(i * m + j, i * m + j + 1, INF);
                }
                else
                    addEdge(i * m + j, t, num);
                sum += num;
            }
        }
        int ans = dinic();
        printf("%d\n", sum - ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章