码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3811 Untrusted Patrol bfs+并查集

时间:2014-09-07 19:52:15      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:http   os   io   ar   for   sp   on   c   amp   

题目链接:点击打开链接

题意:

给定n个点m条边的无向图,k个触发器。

下面k个数表示触发器安装在哪几个点。

下面m行给出边

最后有l个信号,

给出信号发出的触发器的顺序。

每个触发器只会发出一次信号,且一个点只有一个触发器。

有一个人在遍历图。

每经过一个点,那个点的触发器就会发出信号,问是否存在一种走法使得这个人遍历了所有点且触发器发出的信号顺序和给出的一样。

思路:

先把无触发器的点放到图里。

然后根据触发器的信号顺序把点依次加入图中,加入时只添加(与无触发器点相连的边)

然后判断这个点能否与之前的图连通。bfs+并查集判断。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include <queue>
using namespace std;
#define ll int
typedef pair<int,int> pii;
#define M 400010
#define N 200010
int f[N];
int find(int x){return x==f[x]?x:f[x] = find(f[x]);}
void Union(int x,int y){
	int fx = find(x), fy = find(y);
	if(fx==fy)return ;
	if(fx>fy)swap(fx,fy);
	f[fx] = fy;
}
struct Edge{
	int from, to, nex;
}edge[M<<1];
int head[N], edgenum;
void init(){memset(head, -1, sizeof head); edgenum = 0;}
void add(int u, int v){
	Edge E = {u, v, head[u]};
	edge[edgenum] = E;
	head[u] = edgenum++;
}
int n, m, k, l;
int is[N], vis[N];
vector<int>G, E[N];
void ADD(int x){
	for(int i = 0; i < E[x].size(); i++){
		if(is[E[x][i]] == 0)
		add(x, E[x][i]);
	}
	is[x] = 0;
}
void bfs(int x){
	queue<int>q; q.push(x);
	vis[x] = 1;
	while(!q.empty()){
		int u = q.front(); q.pop();
		for(int i = head[u]; ~i; i = edge[i].nex)
		{
			int v = edge[i].to;
			Union(v, x);
			if(vis[v])continue;
			vis[v] = 1;
			q.push(v);
		}
	}
}
bool solve(){
	scanf("%d %d %d",&n,&m, &k);
	init();
	int i, j, u, v;
	for(i = 1; i <= n; i++) {
		vis[i] = is[i] = 0;
		E[i].clear();
	}
	for(i = 1; i <= k; i++) { scanf("%d",&j); is[j] = 1; }
	while(m--){
		scanf("%d %d", &u, &v);
		E[u].push_back(v); E[v].push_back(u);
	}
	G.clear();
	scanf("%d", &l);
	for(i = 1; i <= l; i++) { scanf("%d", &j); G.push_back(j); }
	//若触发器没有全响,就不行
	if(k!=l)return false;
	//若没有触发器一定可以。
	if(k == 0) return true;
	for(i = 1; i <= n; i++)
	{
		if(is[i] == 0)
		{
			for(j = 0; j < E[i].size(); j++)
				if(is[E[i][j]]==0)
					add(i, E[i][j]);
		}
	}
	for(i = 1; i <= n; i++) f[i] = i;
	for(i = 0; i < G.size(); i++) {
		u = G[i];
		ADD(u);
		bfs(u);
		if(i-1>=0){
			find(G[i]); find(G[i-1]);
			if(f[G[i]] != f[G[i-1]])
				return false;
		}
	}
	for(i = 1; i <= n; i++) if(vis[i] == 0) return false;
	return true;
}
int main(){
	int T; scanf("%d",&T);
	while(T--)
		solve() ? puts("Yes"):puts("No");
	return 0;
}
/*
99
5 5 3
1 2 4
1 2
2 3
3 1
1 4
4 5
3
4 2 1
5 5 3
1 2 4
1 2
2 3
3 1
1 4
4 5
3
4 1 2

7 8 3
1 3 5
1 2
1 3
2 3
2 4
3 6
5 4
5 7
6 7
3
5 3 1

7 8 5
3 6 4 5 7
1 2
1 3
2 3
2 4
3 6
5 4
5 7
6 7
5
3 6 4 5 7

7 8 5
3 6 4 5 7
1 2
1 3
2 3
2 4
3 6
5 4
5 7
6 7
5
3 6 5 4 7

8 8 5
3 6 4 5 7
1 2
1 3
2 3
2 4
3 6
5 4
5 7
6 7
5
3 6 4 5 7

ans:
N
Y
Y
Y
N
N

*/


ZOJ 3811 Untrusted Patrol bfs+并查集

标签:http   os   io   ar   for   sp   on   c   amp   

原文地址:http://blog.csdn.net/qq574857122/article/details/39121391

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!