首页 > 代码库 > 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+并查集)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。