BZOJ 4823 老C的方块

 

 把格子分成四类 第一类是蓝线左右的相邻两个格子 第二类为与蓝线左边格子相邻的点 第三类为与蓝线右边格子相邻的点

建边就S朝第二类每个点建边 第二类每个点朝其相邻的第一类建边 第一类从左格子朝右格子建边 第一类朝与其相邻的第三类建边 第三类朝T建边

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef int JQK;
const int dir[4][2] = { 0, -1, -1, 0, 0, 1, 1, 0 };
struct node {
        int x, y, w, color;
} p[100005];
int n, m;
map<pair<int, int>, int> mp;
namespace dinic {
        const int MAXN = 100500;
        const int MAXM = 1000500;
        const int INF = 1000000050;
        int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], ed = 1;
        int S, T, MAXP;
        JQK f[MAXM << 1];
        inline void addedge(int u, int v, JQK cap) {
                to[++ed] = v;
                nxt[ed] = Head[u];
                Head[u] = ed;
                f[ed] = cap;
                to[++ed] = u;
                nxt[ed] = Head[v];
                Head[v] = ed;
                f[ed] = 0;
                return;
        }
        inline bool BFS() {
                int u;
                for (int i = 0; i <= MAXP + 1; i++) {
                        lev[i] = -1;
                }
                //memset(lev, -1, sizeof(lev));
                queue<int>q;
                lev[S] = 0;
                q.push(S);
                while (q.size()) {
                        u = q.front();
                        q.pop();
                        for (int i = Head[u]; i; i = nxt[i])
                                if (f[i] && lev[to[i]] == -1) {
                                        lev[to[i]] = lev[u] + 1;
                                        q.push(to[i]);
                                        /*
                                        if (to[i] == T)
                                        {
                                                return 1;
                                        }
                                        magic one way optimize
                                        */
                                }
                }
                for (int i = 0; i <= MAXP + 1; i++) {
                        cur[i] = Head[i];
                }
                //memcpy(cur, Head, sizeof Head);
                return lev[T] != -1;
        }
        inline JQK DFS(int u, JQK maxf) {
                if (u == T || !maxf) {
                        return maxf;
                }
                JQK cnt = 0, tem;
                for (int &i = cur[u]; i; i = nxt[i])
                        if (f[i] && lev[to[i]] == lev[u] + 1) {
                                tem = DFS(to[i], min(maxf, f[i]));
                                maxf -= tem;
                                f[i] -= tem;
                                f[i ^ 1] += tem;
                                cnt += tem;
                                if (!maxf) {
                                        break;
                                }
                        }
                if (!cnt) {
                        lev[u] = -1;
                }
                return cnt;
        }
        JQK Dinic() {
                JQK ans = 0;
                while (BFS()) {
                        ans += DFS(S, INF);
                }
                return ans;
        }
        void init(int SS, int TT) {
                for (int i = 0; i <= MAXP + 1; i++) {
                        Head[i] = 0;
                }
                ed = 1;
                S = SS;
                T = TT;
                return;
        }
        void work() {
                for (int i = 1; i <= n; i++) {
                        if (p[i].color == 0) {
                                addedge(i, T, p[i].w);
                        } else if (p[i].color == 1) {
                                addedge(S, i, p[i].w);
                        } else if (p[i].color == 2) {
                                for (int j = 0; j < 4; j++) {
                                        int dx = p[i].x + dir[j][0];
                                        int dy = p[i].y + dir[j][1];
                                        int aim = mp[make_pair(dx, dy)];
                                        if (aim == 0) {
                                                continue;
                                        } else if (p[aim].color == 1) {
                                                addedge(aim, i, INF);
                                        } else if (p[aim].color == 3) {
                                                addedge(i, aim, min(p[aim].w, p[i].w));
                                        }
                                }
                        } else {
                                for (int j = 0; j < 4; j++) {
                                        int dx = p[i].x + dir[j][0];
                                        int dy = p[i].y + dir[j][1];
                                        int aim = mp[make_pair(dx, dy)];
                                        if (aim == 0) {
                                                continue;
                                        } else if (p[aim].color == 0) {
                                                addedge(i, aim, INF);
                                        }
                                }
                        }
                }
                printf("%d\n", Dinic());
        }
}
int get_color(int x, int y) {
        if (x & 1) {
                return y % 4 == 1 || y % 4 == 2;
        } else {
                return y % 4 == 3 || y % 4 == 0;
        }
}
int main() {
        int r, c;
        int s, t;
        int x, y, w;
        while (scanf("%d %d %d", &c, &r, &n) == 3) {
                mp.clear();
                for (int i = 1; i <= n; i++) {
                        scanf("%d %d %d", &y, &x, &w);
                        p[i].x = x, p[i].y = y, p[i].w = w;
                        mp[make_pair(x, y)] = i;
                        if ((x + y + 1) & 1) {
                                p[i].color = get_color(x, y) ? 3 : 1;
                        } else {
                                p[i].color = get_color(x, y) ? 2 : 0;
                        }
                        //cout << p[i].color << endl;
                }
                dinic::MAXP = n + 2;
                dinic::init(n + 1, n + 2);
                dinic::work();
        }
        return 0;
}

 

posted @ 2019-09-19 20:00  Aragaki  阅读(114)  评论(0编辑  收藏  举报