[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

分析:
本题作为并查集的基础题目已经成为了并查集必练题目,比较经典,代码实现也较为简单,基本上就是裸的并查集模板了。只要在合并前进行一次判断即可

CODE:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int n,m,f[1005];  
 8 int t[1005],ans,x[1005]; 
 9 int find(int k){
10     if(f[k]==k)return k;
11     return f[k]=find(f[k]);
12 }
13 void merge(int x,int y){
14     x=find(f[x]);
15     y=find(f[y]);
16     f[x]=y;
17     return ;
18 }
19 int main(){
20      cin>>n>>m;
21      for(int i=1;i<=n;i++)
22         f[i]=i;
23     for(int i=1;i<=m;i++){
24         char c;
25         int p,q;
26         cin>>c>>p>>q;
27         if(c=='F') 
28         merge(p,q);  
29         else{
30             if(x[p]==0) 
31             x[p]=find(q);
32             else 
33             merge(q,x[p]); 
34             if(x[q]==0) 
35             x[q]=find(p);
36             else 
37             merge(p,x[q]);
38         } 
39     }
40     for(int i=1;i<=n;i++)
41         t[find(i)]++;
42     for(int i=1;i<=n;i++)
43         if(t[i]) ans++; 
44     cout<<ans;
45     return 0;
46  } 

 

 
posted @ 2019-07-03 20:01  Sword_Art_Online  阅读(134)  评论(0)    收藏  举报