首页 > 代码库 > zoj 3811 Untrusted Patrol(BFS+并查集)

zoj 3811 Untrusted Patrol(BFS+并查集)

题目链接:zoj 3811 Untrusted Patrol

题目大意:给定n,m,k,表示有n个仓库,m条通道,k个传感器,现在给定n个传感器的位置和m条通道,现在要最这n个仓库进行巡逻,要求一次进过给定具有传感器的仓库,每个仓库经过的次数不限,单要求至少进过1次。

解题思路:首先判断是否为联通图,不连通的话肯定到不了。其次判断l是否等于k,如果不等于的话,说明至少有一个仓库到不了,剩下的就是考虑进过仓库的顺序,因为起点不限,所以第一个仓库的位置不会有问题,以第一个仓库为起点,做BFS,碰到有传感器的仓库将传感器关闭,并且将节点标记为1,表示说下一个位置可以直接到达该位置。然后考虑第二个位置,如果第二位置上的传感器没有关闭,则说明由第一个仓库到不了第二个仓库,否则重复操作,以第二个仓库为起点,做BFS

#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>

using namespace std;
const int maxn = 100005;

bool flag;
int N, M, C, t[maxn], v[maxn], f[maxn];
vector<int> g[maxn];

inline int getfar(int x) {
    return x == f[x] ? x : f[x] = getfar(f[x]);
}

void init () {
    scanf("%d%d%d", &N, &M, &C);
    int x, a, b, n = N;

    memset(t, 0, sizeof(t));
    memset(v, 0, sizeof(v));
    for (int i = 0; i <= N; i++) {
        f[i] = i;
        g[i].clear();
    }

    for (int i = 0; i < C; i++) {
        scanf("%d", &x);
        t[x] = 1;
    }

    for (int i = 0; i < M; i++) {
        scanf("%d%d", &a, &b);

        g[a].push_back(b);
        g[b].push_back(a);

        int p = getfar(a), q = getfar(b);
        if (p != q) {
            f[p] = q;
            n--;
        }
    }

    flag = (n == 1);
}

void bfs(int s) {
    queue<int> que;
    t[s] = 0; v[s] = 1;
    que.push(s);

    while (!que.empty()) {
        int u = que.front();
        que.pop();

        for (int i = 0; i < g[u].size(); i++) {
            int k = g[u][i];

            if (v[k] || t[k]) {
                v[k] = 1;
                t[k] = 0;
                continue;
            }

            v[k] = 1;
            que.push(k);
        }
    }
}

bool judge () {
    int n, x;
    scanf("%d", &n);

    if (n < C)
        flag = false;

    for (int i = 0; i < n; i++) {
        scanf("%d", &x);
        if (flag == false || (t[x] && i)) {
            flag = false;
            continue;
        }
        bfs(x);
    }
    return flag;
}

int main () {
    int cas;
    scanf("%d", &cas);
    while (cas--) {
        init();
        printf("%s\n", judge() ? "Yes" : "No");
    }
    return 0;
}

zoj 3811 Untrusted Patrol(BFS+并查集)