1. 程式人生 > >P1892 [BOI2003]團夥

P1892 [BOI2003]團夥

clu clas for mes lse 是我 cin 慢慢 個數

P1892 [BOI2003]團夥

題目描述

1920年的芝加哥,出現了一群強盜。如果兩個強盜遇上了,那麽他們要麽是朋友,要麽是敵人。而且有一點是肯定的,就是:

我朋友的朋友是我的朋友;

我敵人的敵人也是我的朋友。

兩個強盜是同一團夥的條件是當且僅當他們是朋友。現在給你一些關於強盜們的信息,問你最多有多少個強盜團夥。

輸入輸出格式

輸入格式:

輸入文件gangs.in的第一行是一個整數N(2<=N<=1000),表示強盜的個數(從1編號到N)。 第二行M(1<=M<=5000),表示關於強盜的信息條數。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敵人。輸入數據保證不會產生信息的矛盾。

輸出格式:

輸出文件gangs.out只有一行,表示最大可能的團夥數。

輸入輸出樣例

輸入樣例#1:
6
4
E 1 4
F 3 5
F 4 6
E 1 2

  

輸出樣例#1:
3

  


先說一下思路:

對於只有朋友信息的數據就不用說了。對於敵人的信息,我們可以給每一個人i設置一個敵人集合E[i],當輸入i和j時,我們就把i和E[j]合並,把j和E[i]合並。

值得一提的是,要註意空集的處理,所謂空集就是一開始的時候,每個人都沒有敵人。

昨天晚上做了一晚上卡在了50分,今天又接著來啃,問同學,同學說我的想法很對,叫我自己慢慢調(WCNM我要是調的出來就不找你了)

沒辦法,慢慢找嘍。

先給大家看看我的50分的代碼。

#include <iostream>
#include <cstdio>

using namespace std;

int n, m, Ans, x, y;

int f[1008], E[1008];

char C;

bool vis[1008];

int find(int x) {
	if(x == f[x]) return f[x];
	else return f[x] = find(f[x]);
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i=1; i<=n; i++) f[i] = i;
	for(int i=1; i<=m; i++) {
		cin>>C>>x>>y;
		int xx, yy;	
		if(C == ‘E‘) {
			if(E[x] != 0) {
				f[y] = find(E[x]);
			}
			if(E[y] != 0) {
				f[x] = find(E[y]);
			}
			E[x] = y, E[y] = x;
		}
		if(C == ‘F‘) {
			f[x] = find(y);
		}
	}
	for(int i=1; i<=n; i++) {
		if(!vis[find(i)]) {
			vis[find(i)] = 1;
			Ans++;
		}
	}
	printf("%d", Ans);
}

  

不知道大家看出什麽問題了沒。

沒看出的同學可要小心了,

看一下我的合並集合時候的操作,是不是把之前合並好的集合都打亂了。

為什麽?因為我合並時修改的是f[x]的值,而不是f[find(x)]的值,這就會導致很可怕的錯誤。

往後的此類操作都是這樣的。

好了,說到這裏該放上AC的代碼了

#include <iostream>
#include <cstdio>

using namespace std;

int n, m, Ans, x, y;

int f[1008], E[1008];

char C;

bool vis[1008];

int find(int x) {
	if(x == f[x]) return x;
	else return f[x] = find(f[x]);
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i=1; i<=n; i++) f[i] = i;
	for(int i=1; i<=m; i++) {
		cin>>C>>x>>y;
		if(C == ‘E‘) {
			if(E[x] != 0) {	
				f[find(y)] = find(E[x]);
			}
			else E[x] = find(y);
			if(E[y] != 0) {
				f[find(x)] = find(E[y]);
			}
			else E[y] = find(x);
		}
		if(C == ‘F‘) {
			f[find(x)] = find(y);
		}
	}
	for(int i=1; i<=n; i++) {
		if(!vis[find(i)]) {
			vis[find(i)] = 1;
			Ans++;
		}
	}
	printf("%d", Ans);
}

  

P1892 [BOI2003]團夥