您的位置:首页 > 其它

HDU 2473 并查集

2016-05-27 13:57 288 查看
点击打开链接

题意:给了两种操作,M u v将u与v连接到一起,S u 将u从它的集合中拿出来,但是不改变集合中的其他元素已有的关系

思路:就是直接并查集,然后有了个删点的操作,这与之前写的ZOJ 3789的删除操作是一样的,找个数组代替就可以了,简单~~~ PS:加了路径压缩跑得还是那么慢,org
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INT=0x3f3f3f3f3f3f3f3fll;
const int maxn=1100010;
int f[maxn],ff[maxn];
int find1(int x){
int k,r,j;
r=x;
while(r!=f[r]) r=f[r];
k=x;
while(k!=r){
j=f[k];
f[k]=r;
k=j;
}
return r;
}
void unite(int a,int b){
int aa=find1(a);
int bb=find1(b);
if(aa==bb) return ;
f[aa]=bb;
}
int vis[maxn];
int main(){
int n,m,u,v,cas=1;
char ch[10];
while(scanf("%d%d",&n,&m)!=-1){
if(n==0&&m==0) break;
for(int i=0;i<=n+m;i++){
f[i]=ff[i]=i;vis[i]=0;
}
int ans=n,sum=0;
for(int i=0;i<m;i++){
scanf("%s",ch);
if(ch[0]=='M'){
scanf("%d%d",&u,&v);
unite(ff[u],ff[v]);
}else if(ch[0]=='S'){
scanf("%d",&u);
ff[u]=n++;f
=n;
}
}
for(int i=0;i<ans;i++){
int t=find1(ff[i]);
vis[t]=1;
}
for(int i=0;i<n;i++) if(vis[i]) sum++;
printf("Case #%d: %d\n",cas++,sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: