您的位置:首页 > 其它

ZOJ 3811 Untrusted Patrol 并查集 染色 BFS

2014-09-08 10:18 387 查看
题意:有N个城市,M条路。有K个传感器,分布在给定的K个城市中。传感器只会在第一次到达该城市时触发。现在给出传感器触发的先后顺序,问是否有方案遍历完所有的城市。

思路:第一点很容易想到的是:如果触发的传感器的数量少于传感器的总数量,那么一定没有遍历完所有城市。

第二点:对于没有放传感器和传感器已经触发的城市,还有所有的路,我们的访问次数的无限制的。所以,我们这些城市的访问顺序是没有先后的,可以按照任意的顺序访问任意多次。现在问题的关键就是:能不能按照触发顺序访问完放置传感器的城市。我们可以有以下的思路:对于每个放置传感器的城市,我们可以通过搜索的得到从他出发,不触发任何传感器且能到达的城市。同时,这些城市中如果有一个和前面已经处理的城市的集合相连的路,那就可以得到一条路,按照传感器的触发顺序,到达前一个城市。之后将集合加入到已经处理的城市的集合,即,可以无限次访问的集合。如果找不到,那就说明无法到达前一个城市。

第三点:整个图必须是连通的,要不然总会有一个点无法访问。

代码如下:

#include <bits/stdc++.h>

using namespace std;

const int MAX = 1000100;
int N,M,K,L;
int tot;
int head[MAX];
int nxt[MAX];
int to[MAX];
int used[MAX];
bool vis[MAX];
int order[MAX];
int que[MAX], front, tail;
int temp[MAX],ttop;
bool cn;

template<class T>
inline bool read(T &n){
T x = 0, tmp = 1; char c = getchar();
while ((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();
if (c == EOF) return false;
if (c == '-') c = getchar(), tmp = -1;
while (c >= '0' && c <= '9') x *= 10, x += (c - '0'), c = getchar();
n = x*tmp;
return true;
}

template <class T>
inline void write(T n) {
if (n < 0) {
putchar('-');
n = -n;
}
int len = 0, data[20];
while (n) {
data[len++] = n % 10;
n /= 10;
}
if (!len) data[len++] = 0;
while (len--) putchar(data[len] + 48);
}
void init(){
memset(head,-1,sizeof(int) * (N + 1));
memset(used,0,sizeof(int)*(N+1));
tot = 0;
}

void addedge(int u, int v){
to[tot] = v;
nxt[tot] = head[u]; head[u] = tot++;
to[tot] = u;
nxt[tot] = head[v]; head[v] = tot++;
}

bool bfs(int s){
bool sig=false;
ttop=0;
front = tail = 0;
que[tail++] = s;
used[s] = 2;
ttop++;
temp[ttop]=s;
while(front < tail){
int u = que[front++];
//printf("%d\n",u);
for(int i = head[u]; i != -1; i = nxt[i]){
int v = to[i];
if (used[v]==1) sig=true;
if(used[v] || vis[v]) continue;
used[v]=2;
ttop++;
temp[ttop]=v;
que[tail++] = v;
}
}
for(int j=1;j<=ttop;j++)
{
used[temp[j]]=1;
}
return sig;
}

int main(void)
{
//freopen("input.txt","r",stdin);
int T;
int tmp;
int u,v;
read(T);
while(T--){
read(N),read(M),read(K);
init();
memset(vis,0,sizeof(bool) * (N + 1));
for(int i = 0 ; i < K; ++i)
read(tmp);
for(int i = 0; i < M; ++i){
read(u),read(v);
addedge(u,v);
}
read(L);
for(int i = 0 ; i < L; ++i){
read(order[i]);
vis[order[i]] = true;
}

if(L < K ) puts("No");
else{
vis[order[0]] = false;
bfs(order[0]);
bool sig=true;
for(int i = 1; i < K; ++i){
vis[order[i]] = false;
if (!bfs(order[i]))
{
sig=false;
break;
}
}
for (int i=1;i<=N;i++)
{
if (!used[i])
{
sig=false;
break;
}
}
if(sig) puts("Yes");
else puts("No");
}
}
return 0;
}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: