程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UESTC 1811 Hero Saving Princess

UESTC 1811 Hero Saving Princess

編輯:C++入門知識

題意:T個測試數據   n m //n個點 m條邊   m條無向邊   que//下面有que個數據   a b // 表示a點的鑰匙在b中       問,從0點開始能否遍歷所有的點       思路:用BFS搜一遍即可,注意圖是否連通,用並查集判斷一下   BFS()時,q為正常隊列,p為走到那個點是鎖住時將q中點移到p中  

#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <cstring>
#include <set>
#include <vector>
#define inf 1073741824
#define N 100100
#define ll int
using namespace std;
inline ll Max(ll a,ll b){return a>b?a:b;}

int lock[N],key[N],n,m;//lock=0表示沒鎖 ,key[i] 表示i房間中的鑰匙,沒有鑰匙=-1
vector<int>G[N];
queue<int>q,p;//q表示bfs的沒鎖的點,p表示被鎖的點

int f[N];
int find(int x){
	if(f[x]==x)return x;
	return f[x]=find(f[x]);
}

bool vis[N],inp[N];

void BFS(){
	memset(vis,0,sizeof(vis));
	memset(inp,0,sizeof(inp));
	q.push(0);
	vis[0]=true;
	int i,v,u,len;
	bool change=true;

	while(1)
	{
		change=false;//跳出條件是有新的點可以走
		while(!q.empty())
		{
			u=q.front(); q.pop();
			len=G[u].size();
			for(i=0;i<len;i++)
			{
				v=G[u][i];
				if(lock[v]==-1)
				{
					if(inp[v]==false)
						p.push(v),inp[v]=true;//如果鎖著且不在p中
					continue;
				}
				if(vis[v]==false)
				{
					vis[v]=true;
					q.push(v);
					change=true;
					if(key[v]!=-1)//說明有鑰匙
						lock[key[v]]=0;					
				}
			}
		}
		if(change==false)break;
		if(!p.empty())
		{
			len=p.size();
			while(len--)
			{
				int u=p.front();p.pop();
				if(lock[u]>=0) //u點沒有鎖
					q.push(u),vis[u]=true;
				else p.push(u);				
			}
		}

	}
}

int main(){
	int i,j,a,b,que;
	int T,Cas=1;scanf("%d",&T);

	while(T--){
		memset(lock,0,sizeof(lock));
		memset(key,-1,sizeof(key));
		scanf("%d%d",&n,&m);
		for(i=0;i<n;i++)G[i].clear(),f[i]=i;
		
		while(m--)
		{
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
			f[find(a)]=find(b);
		}
		scanf("%d",&que);
		while(que--)
		{
			scanf("%d%d",&b,&a);
			key[a]=b;
			lock[b]=-1;
		}


		for(i=0;i<n;i++)find(i);
		bool fu=false;
		for(i=0;i<n;i++)
			if(f[i]!=f[0])
			{
				fu=true;
				break;
			}
			if(fu){printf("Case #%d: No\n",Cas++);continue;}

		while(!q.empty())q.pop();
		while(!p.empty())p.pop();
		if(key[0]!=-1)lock[key[0]]=0;//起點房間如果有鑰匙直接開門
		BFS();
		if(!p.empty())printf("Case #%d: No\n",Cas++);//p表示鎖著的門,如果還有鎖著的門就說明沒有走到所有的點
		else printf("Case #%d: Yes\n",Cas++);
	}
	return 0;
}
/*
99
2 1
0 1
0
3 2
0 1
1 2
1
1 2

7 9
0 1
2 0
2 5
5 1
5 6
5 2
1 3
3 6
1 4
3
4 2
2 0
6 4

7 9
0 1
2 0
2 5
5 1
5 6
5 2
1 3
3 6
1 4
1
2 2

3 4
0 1
1 0
0 1
2 0
2
1 2
2 1

1 0
0

2 1
1 0
1
1 1

2 1 
1 0
1
1 0

2 0
0


ans:
y
n
y
n
n
y
n
y

*/

 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved