本文主要是介绍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+并查集)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!