1. 程式人生 > >哈爾濱理工大學第七屆程式設計競賽決賽(網路賽-高年級組)G.幼兒園戰爭

哈爾濱理工大學第七屆程式設計競賽決賽(網路賽-高年級組)G.幼兒園戰爭

題目描述

幼兒園的孩子們正在做遊戲,每個人都有自己的幫派,幫派之間打架,然後贏者吞併弱者擴大自己的勢力。最開始每個孩子的幫派中只有自己,然後接下來有會有兩個人打架,這兩個人會集結自己所屬的勢力開始打架,打贏的一方就會吞併輸的一方,當然如果x,y是一個勢力就不會打起來。有些聰明的小朋友會將自己的糖分給其他小朋友引誘他離開所屬勢力加入到自己勢力。又有一些小朋友會對現在的勢力不滿,然後反叛出去自立門戶。

作為打架的雙方,只有人數大於另一方才能打贏。即:人數相等則沒有輸贏,兩個幫派沒有變化。

幼兒園裡面共有N個孩子,接下來有M次操作,操作有如下4種
1)  query      查詢現在有多少個勢力。
2)  fight x y  表示x,y打架.並輸出"z is winner!"勝利的一方(z是x或y),如果沒有打平則輸出"Either is winner!".如果x,y屬於同一個勢力不會打架,當然也不用輸出.
3)  tempt x y  表示x誘惑y、將y拉入x的勢力。
4)  revolt x   表示x反叛,(自立門戶)

輸入描述:

第一行輸入一個T代表有T組資料
接下來第一行有兩個整數N,M,代表N個孩子,M次操作。
接下來有M行。每行輸入有如下三種。
1) query
2) fight x y
3) tempt x y
4) revolt x
1<=T<=10;
1<=N,M<=100000;
1<=x,y<=N;

輸出描述:

第一行輸出"Case #x:",表示第x組測試資料。
接下來輸出查詢結果,每個結果佔一行。
示例1

輸入

1
5 9
query
tempt 1 2
query
fight 4 5
query
fight 2 3
query
revolt 2
query

輸出

Case #1:
5
4
Either is winner!
4
2 is winner!
3
4

隊友寫的並查集超時 我用set水一波過了哈哈哈

#include <bits/stdc++.h>
using namespace std;
 
set<int> is[100005];
int location[100005];
 
int main() {
   int t,n,m,kase=1;
   cin>>t;
   while(t--){
   	printf("Case #%d:\n",kase++);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) { is[i].insert(i); location[i]=i;}
    int fp=n;
    int num=n;
    while(m--){
    	char s[10];
    	scanf("%s",s);
    	if(s[0]=='q'){
    		cout<<num<<endl;
    	}
    	else if(s[0]=='f'){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		int xa=x;
    		int ya=y;
    		x=location[x];
    		y=location[y];
    		if(x==y) continue;
    		if(is[x].size()>is[y].size()){
    			set<int>::iterator ite1 = is[y].begin();
    			for(;ite1!=is[y].end();ite1++){
    				int g = *ite1;
    				location[g]=x;
    				is[x].insert(g);
    			}
    			is[y].clear();
    			cout<<xa<<" is winner!"<<endl;
    			num--;
    		}
    		else if(is[x].size()<is[y].size()){
    			set<int>::iterator ite2 = is[x].begin();
    			for(;ite2!=is[x].end();ite2++){
    				int g1 = *ite2;
    				location[g1]=y;
    				is[y].insert(g1);
    			}
    			is[x].clear();
    			cout<<ya<<" is winner!"<<endl;
    			num--;
    		}
    		else{
    			cout<<"Either is winner!"<<endl;
    		}
    			
    	}
    	else if(s[0]=='t'){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		int xl = location[x];
    		is[xl].insert(y);
    		int yl = location[y];
			is[yl].erase(y);
    		location[y]=xl;
    		if(is[yl].empty())
    		num--;
    	}
    	else{
    		int x;
    		scanf("%d",&x);
    		int xl = location[x];
    		if(is[xl].size()==1) continue;
    		while(!is[fp].empty()) fp++;
    		is[fp].insert(x);
    		is[xl].erase(x);

    		location[x]=fp;
    		num++;
    		
    	}
    }
    for(int i=1;i<=fp;i++) is[i].clear();
    memset(location,0,sizeof(location));
    }
    
    		
  
}