zoukankan      html  css  js  c++  java
  • UESTC 1811 Hero Saving Princess

    九野的博客,转载请注明出处 http://blog.csdn.net/acmmmm/article/details/11104265

    题目链接 :http://222.197.181.5/problem.php?pid=1811

    题意: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
    ",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
    ",Cas++);//p表示锁着的门,如果还有锁着的门就说明没有走到所有的点
    		else printf("Case #%d: Yes
    ",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
    
    */
    
  • 相关阅读:
    Tomcat Manager用户配置详解
    自动更新Chromium
    如何方便快速在指定文件夹打开命令行
    让Chrome 接管邮件连接,收发邮件更方便了
    Chrome扩展程序的二次开发:把它改得更适合自己使用
    更改Photoshop 语言为英语(无需语言包)
    Chrome 控制台新玩法-console显示图片以及为文字加样式
    JavaScript—之对象参数的引用传递
    jQuery 绑定事件到动态创建的元素上
    JavaScript –类型之我晕
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3303897.html
Copyright © 2011-2022 走看看