HDU 6735 结论网络流 机器人不重叠路径

我们可以得到一个结论:没有两个机器人走过的路会重叠

所以题目就转变为了能不能让机器人的路径不重叠且每个机器人能到达终点

直接一个点朝他四连通方向的四个点连容量为1的边即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef int JQK;
int n, m;
char ch[105][105];
const int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}};
namespace dinic {
        const int MAXN = 10050;
        const int MAXM = 100050;
        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;
        }
        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(int aim) {
                int u, v, c;
                for (int i = 1; i <= n; i++) {
                        for (int j = 1; j <= m; j++) {
                                if (ch[i][j] == '1') {
                                        continue;
                                }
                                for (int k = 0; k < 4; k++) {
                                        int dx = i + dir[k][0];
                                        int dy = j + dir[k][1];
                                        if (dx >= 1 && dx <= n && dy >= 1 && dy <= m) {
                                                if (ch[dx][dy] == '1') {
                                                        continue;
                                                }
                                                addedge((i - 1)*m + j, (dx - 1)*m + dy, 1);
                                        }
                                }
                        }
                }
                int ans = Dinic();
                printf(ans == aim ? "Yes\n" : "No\n");
        }
}
int main() {
        int TNT, a, b, x, s, t;
        scanf("%d", &TNT);
        while (TNT--) {
                scanf("%d %d", &n, &m);
                scanf("%d %d", &a, &b);
                dinic::MAXP = n * m + 5;
                s = n * m + 1;
                t = s + 1;
                dinic::init(s, t);
                for (int i = 1; i <= n; i++) {
                        scanf("%s", ch[i] + 1);
                }
                for (int i = 1; i <= a; i++) {
                        scanf("%d", &x);
                        dinic::addedge(s, x, 1);
                }
                for (int i = 1; i <= b; i++) {
                        scanf("%d", &x);
                        dinic::addedge(x + (n - 1)*m, t, 1);
                }
                if (a > b) {
                        printf("No\n");
                        continue;
                }
                dinic::work(a);
        }
        return 0;
}

 

posted @ 2019-10-11 18:29  Aragaki  阅读(392)  评论(0编辑  收藏  举报