合纵连横
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
乱世天下,诸侯割据。每个诸侯王都有一片自己的领土。但是不是所有的诸侯王都是安分守己的,实力强大的诸侯国会设法吞并那些实力弱的,让自己的领土面积不断扩大。而实力弱的诸侯王为了不让自己的领土被吞并,他会联合一些其他同样弱小的诸侯国,组成联盟(联盟不止一个),来共同抵抗那些强大的诸侯国。 强大的诸侯国为了瓦解这些联盟,派出了最优秀的间谍来离间他们,使一些诸侯国退出联盟。最开始,每个诸侯国是一个联盟。
有两种操作
1、U x y 表示x和y在同一个联盟。(0≤x,y<n)
2、D x 表示x退出联盟。
-
输入
-
多组测试数据
第一行两个数,n和m(1 ≤ n≤ 10^5, 1 ≤ m ≤10^5),分别表示诸侯国的个数和操作次数。
接下来有m行操作
输出
- 输出联盟的个数 样例输入
-
5 7 U 0 1 U 1 2 U 0 3 D 0 U 1 4 D 2 U 0 2 10 1 U 0 9
样例输出
-
Case #1: 2 Case #2: 9
-
多组测试数据
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 300000
using namespace std;
int per[maxn * 4];
int vis[maxn * 4];
int ans, n, m;
void init(){
ans = n + n;
for(int i = 0; i < n; ++i)
per[i] = i + n;
for(int j = n; j <= n + n + m; j++)
per[j] = j;
memset(vis, 0 ,sizeof(vis));
}
int find(int x){
if(x == per[x])
return x;
return per[x] = find(per[x]);
}
void jion (int x, int y){
int fx = find(x);
int fy = find(y);
if(fx != fy)
per[fx] = fy;
}
void del(int x){
per[x] = ans++;
}
void getmap(){
char str[10];
int a,b;
while(m--){
scanf("%s", &str);
if(str[0] == 'U'){
scanf("%d%d", &a, &b);
jion(a, b);
}
else {
scanf("%d", &a);
del(a);
}
}
}
int main (){
int k = 1;
while(scanf("%d%d", &n, &m)!=EOF){
init();
getmap();
int ans = 0;
for(int i = 0; i < n ; ++i){
int x= find(i);
if(!vis[x]){
ans++;
vis[x] = 1;
}
}
printf("Case #%d: %d\n", k++, ans);
}
return 0;
}