ACdream 1056 Bad Horse (种类并查集)

Bad Horse

Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

Problem Description

As the leader of the Evil League of Evil, Bad Horse has a lot of problems to deal with.

Most recently, there have been far too many arguments and far too much backstabbing in the League, so much so that Bad Horse has decided to split the league into two departments in order to separate troublesome members.

Being the Thoroughbred of Sin, Bad Horse isn't about to spend his valuable time figuring out how to split the League members by himself.

That what he's got you -- his loyal henchman -- for.

Input

The first line of the input gives the number of test cases, T (1 ≤ T ≤ 100).

T test cases follow.

Each test case starts with a positive integer M (1 ≤ M ≤ 100) on a line by itself -- the number of troublesome pairs of League members.

The next M lines each contain a pair of names, separated by a single space.

Each member name will consist of only letters and the underscore character "_".

Names are case-sensitive.

No pair will appear more than once in the same test case.

Each pair will contain two distinct League members.

Output

For each test case, output one line containing "Case #x: y", where x is the case number (starting from 1) and y is either "Yes" or "No", depending on whether the League members mentioned in the input can be split into two groups with neither of the groups containing a troublesome pair.

Sample Input

2
1
Dead_Bowie Fake_Thomas_Jefferson
3
Dead_Bowie Fake_Thomas_Jefferson
Fake_Thomas_Jefferson Fury_Leika
Fury_Leika Dead_Bowie

Sample Output

Case #1: Yes
Case #2: No



大致题意:据说这题是出自google挑战赛吧,可是偶然在ACdream上见到。题目是讲一个教派里面有好多帮派。如今要将这些帮派划分成两个大帮派。当中题目中给出了好多组相互对立的帮派,让你推断这些帮派能否够划分为两个大帮派。


解题思路:这里用到了非经常见的并查集。可是这里有点小小的变化。就是要开两个空间,就是每一个并查集都开了一个额外的空间。这里详细处理的时候是在200以后的空间里再存有一下。

                   先用map把string映射到int(这里用map将我们要进行编号操作的string(字符串)映射到int,是一个非常方便的处理string问题的手段。)。然后合并a和b+200。a+200和b,当a与b或a+200与b+200在同一集合时,就产生了矛盾。


                   网上也有大神讲能够用二分图匹配做。临时还不懂,就附上网址,感兴趣的自己看吧       二分图匹配具体解释


AC代码:

#include <cstdio>
#include <algorithm>
#include <map>
#include <string>
#include <iostream>

using namespace std;
const int maxn = 10001;

int f[maxn];
map<string, int> m;

int find(int x){
	return x == f[x] ? x : f[x] = find(f[x]);
}

void unin(int x, int y){
	x = find(x);
	y = find(y);
	if(x != y){
		f[x] = y;
	}
}

int main(){
	#ifndef ONLINE_JUDGE
	freopen("in.txt","r",stdin);
	#endif

	int T, n;
	string a, b;
	scanf("%d", &T);
	int cnt = 0;
	for(int t=1; t<=T; t++){
		scanf("%d", &n);
		int flag = 1;

		for(int i=0; i<maxn; i++)         //初始化f[]
		f[i] = i;

		for(int i=0; i<n; i++){
			cin >> a >> b;
			if(!m[a])   m[a] = cnt++;
			if(!m[b])   m[b] = cnt++;
			if(find( m[a] ) == find( m[b] ) || find( m[a]+200 ) == find( m[b]+200 ) )       //产生矛盾的推断
				flag = 0;
			else{
				unin(m[a], m[b]+200);
				unin(m[a]+200, m[b]);
			}
		}
		printf("Case #%d: %s\n", t, flag ?

"Yes" : "No"); } return 0; }



posted @ 2017-04-13 11:33  jzdwajue  阅读(235)  评论(0编辑  收藏  举报