您的位置:首页 > 其它

zoj 3811 Untrusted Patrol(BFS+并查集)

2014-09-08 14:37 288 查看
题目链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: