1. 程式人生 > >數算實習 A bug's life 並查集

數算實習 A bug's life 並查集

背景 Hopper教授正在研究一種稀有物種的性行為。他假設他們有兩種不同的性別,他們只與異性發生性行為。每個個體的編號都印在他們的背上。 問題 給出一個bug之間的性行為列表,確定實驗是否支援他的假設:該物種之間不存在同性戀關係。

輸入 輸入的第一行包含實驗的數量。每個實驗的第一行給出了bug數(至少一個,最多2000個)和性行為數(最多1000000)。在以下數行中,每行給出發生性行為的兩隻bug的編號。bug從1開始連續編號。 輸出 每個場景的輸出都是一行包含“Scenario #i:”,其中i是從1開始的實驗編號。如果實驗與他對bug的性行為的假設一致,則輸出“No suspicious bugs found!” 。 如果Hopper教授的假設是絕對錯誤的,則輸出“Suspicious bugs found!”。

樣例輸入 2 3 3 1 2 2 3 1 3 4 2 1 2 3 4 樣例輸出 Scenario #1: Suspicious bugs found!

Scenario #2: No suspicious bugs found!

  #include  <iostream> 
  using  namespace std ; 
  // 1表示有關係0表示無關
 
  const  int MAX = 2000 ; 
  int parent [ MAX +10 ]; 
  int relation [ MAX +10 ]; 
  int t ; 
  int n , k ;
  
  int Getroot(int a)
  {
  	if(a==parent[a])
	  {
  		return a;
	  }
    int t=parent[a];
  	parent[a]=Getroot(parent[a]);
  	relation[a]=(relation[a]+relation[t])%2;
  	return parent[a];
  } 
  
   void merge(int a,int b)
  {
  		int pa=Getroot(a);
	  	int pb=Getroot(b);                    //壓縮 
	  	parent[pa]=pb;
	  	if(relation[a]+relation[b]!=1)
	  	  relation[pa]=1;
	  	else
	  	  relation[pa]=0;
  } 
   
   int main()
  {
  	cin>>t;
    for(int j=1;j<=t;j++)
	{
	  scanf("%d%d",&n,&k);
	  for (int i=1;i<=n;i++)
	  {
		parent[i]=i;
		relation[i]=0;
      }
	  int flag=0;
	  for (int i=1;i<=k;i++)
	  {
	  	int a,b;          //編號 
	  	scanf("%d%d",&a,&b);
	  	int pa=Getroot(a);
	  	int pb=Getroot(b);                    //壓縮 
	  	if(pa!=pb)
		  {
	  		merge(a,b); 
		  }
	  	else
		  {
	  		if(relation[a]==relation[b]) 
			  {
			    flag=1;
			    continue;
			  }
		  }
	  }	
  		if(flag==0)
  		cout<<"Scenario #"<<j<<":"<<endl<<"No suspicious bugs found!"<<endl<<endl;
  		else
  		cout<<"Scenario #"<<j<<":"<<endl<<"Suspicious bugs found!"<<endl<<endl;
  	}
  	return 0;
  }