Island Communication -遍历邻接表

J - Island Communication
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

Description

Once upon a time, human have not invented boats and planes, bridges were the most important things in communication among islands. There is a large kingdom consists of N islands. One day, a terrible war broken out in this country. Due to the war, there might be several bridges being built or destroyed in each day. Tom, one of your best friends, is a business man. People always earn lots of money during the war, and certainly Tom doesn't want to lose this chance. But he doesn't know whether he can get to one island from another island, so he comes to you for help.

Input

There are multiple cases. The first line of each case consists of two integers N and M (1≤N≤500, 1≤M≤50000), indicates the number of islands and the number of operations. The indies of the island are from 1 to N. Then comes M lines of operations. There are three kinds of operations:

  1. I x y: means they build a bridge connects island x and island y
  2. D x y: means they destroy the bridge which connects island x and island y
  3. Q x y: Tom want to know whether he can get to island y from island x

Assume there are no bridges at the beginning, and each bridge will be built at most once(means when one bridge is destroyed, you can never build it any more)

Output

In the first line, you must output the case number. And for each query, you must output "YES" if you can get to island y from island x. otherwise output "NO".

Print a blank line between cases.

Sample Input

5 9
I 1 2
I 2 3
Q 1 3
I 1 3
I 2 4
I 4 5
D 1 2
D 2 3
Q 1 5

Sample Output

Case 1:
YES
NO

  

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;


int n,m;
int op[50005][3]; 
vector <int> map[505]; 
int vis[505]; 
vector <int> delete_edge[505]; 


queue <int > check;

int  query(int x,int y)  // map[x] 中 搜寻y的踪影    //递归
{
    if (x==y) return 1;          //自己与自己属于连通 
	   vector<int>::iterator final = find( map[x].begin(), map[x].end(), y ); //查找y 
	   if (final!=map[x].end()) return 1;        //找到为连通
	   
	   int i;
	   for (i=0;i<map[x].size();i++)    //遍历map[x] vector
	   {
		   
		 //  printf("%d\n",map[x][i]);
		   if (  vis[ map[x][i]  ] ==0    )       // vis[]=0 表示没遍历过该边
		   {
			   vis[  map[x][i] ] =1;          //标记已经遍历过,下次不再进入此边
			   int ans=query( map[x][i] ,y);    //   递归查找
			   if (ans)  return 1;
		   }
		   
	   }
	   return 0;
	   
}


int main()
{
	
	int i,j,k,t; 
	char tmp;
	int a,b;
	int cnt=0;	
	int mark=1;
	while(	scanf("%d%d",&n,&m)!=EOF)
	{
		
		getchar();
		if (mark)
		{
			mark=0;
		}
		else
			printf("\n");
		printf("Case %d:\n",++cnt);
		
		memset(map,0,sizeof(map));
		for (i=1;i<=m;i++)
		{
			scanf("%c %d %d",&tmp,&a,&b);
			getchar();
			if (tmp=='I')
			{
				op[i][0]=1;
				op[i][1]=a;
				op[i][2]=b;
			}
			else
				if (tmp=='D')
				{
					op[i][0]=2;
					op[i][1]=a;
					op[i][2]=b;
				}
				else
					if (tmp=='Q')
					{
						op[i][0]=3;
						op[i][1]=a;
						op[i][2]=b;
					}
					
		}
		/*	printf("\n");
		for (i=1;i<=n;i++)
		{
		for (j=1;j<=n;j++)
		{
		printf("%d ",map[i][j]);
		
		  }
		  printf("\n");
		  }
		  printf("\n");
		*/
		for (i=1;i<=m;i++)
		{
			if (op[i][0]==1)
			{ 
				int t1=op[i][1];
				int t2=op[i][2]; 
				vector<int>::iterator delete_result = find( delete_edge[t1].begin(), delete_edge[t1].end(), t2 ); //查找t2
			 
				if (delete_result!=delete_edge[t1].end()) continue;
				
				vector<int>::iterator result = find( map[t1].begin(), map[t1].end(), t2 ); //查找t2
				if (result!=map[t1].end()) continue;
				else
				{
					map[t1].push_back(t2);
					map[t2].push_back(t1);
					
				}
			}
			
			if (op[i][0]==2)
			{
				int t1=op[i][1];
				int t2=op[i][2];
				delete_edge[t1].push_back(t2);
				delete_edge[t2].push_back(t1);
		 	vector<int>::iterator del = find( map[t1].begin(), map[t1].end(), t2 ); //查找t2
		if (del!=map[t1].end())					 *del=t1;                                       //注意如果要找到t2才能删除。否则删除的是 (NULL指针) 会导致程序出错
								  del = find( map[t2].begin(), map[t2].end(), t1 ); //查找t1
			if (del!=map[t2].end())				 *del=t2;   //把原vector中要删除的元素换为自身,而不erease,是因为后者效率太低,要改变数组大小+移动数据;

			}
			
			if (op[i][0]==3)
			{
				int t1=op[i][1];
				int t2=op[i][2];
				memset(vis,0,sizeof(vis));
				vis[t1]=1;
				while(!check.empty())  check.pop();
				int ans=query(t1,t2);
				if (ans)
					printf("YES\n");
				else
					printf("NO\n");
				
			}
			
			
		}
		
		
		for (i=0;i<=n;i++)
		{
			map[i].clear();
			delete_edge[i].clear();
		} 
		
	}
	
	
	
	
	return 0;
	
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值