poj1988 题解 更厉害的

链接:poj1988

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(regiser int i=x;i>=y;--i)
#define ll long long
using namespace std;
const int N=1e5+7;
int f[N],rl[N],n,a,b,nm[N];
char c;

int (int x){
if(f[x]==x)return x;
int t=find(f[x]);
rl[x]+=rl[f[x]];
return f[x]=t;
}

inline void un(int x,int y){
int a=find(x);
int b=find(y);
f[b]=a;
rl[b]=nm[a];
nm[a]+=nm[b]; //更新b的长度
//nm[a]=0;
}

int main(){
ios::sync_with_stdio(false);
cin>>n;
rep(i,1,30000)f[i]=i,nm[i]=1;
rep(i,1,n){
cin>>c>>a;
if(c=='M'){cin>>b;un(a,b);}
else cout<<nm[find(a)]-rl[a]-1<<endl;
}
return 0;
}

更厉害的

  • 看了大神的博客,发现,根本不需要多开一个rl数组保存列长度
  • 果然是太弱了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
using namespace std;
const int N=1e5+7;
int f[N],dis[N],n,a,b;
char c;
int (int x){
if(f[x]<0)return x;
int t=find(f[x]);
dis[x]+=dis[f[x]];
return f[x]=t;
}

inline void un(int x,int y){
x=find(x);
y=find(y);
if(x!=y){
dis[y]=(-f[x]);
f[x]+=f[y];
f[y]=x;
}
}

int main(){
ios::sync_with_stdio(false);
cin>>n;
memset(f,-1,sizeof(f));
rep(i,1,n){
cin>>c>>a;
if(c=='M'){cin>>b; un(a,b);}
else cout<<f[find(a)]*(-1)-dis[a]-1<<endl;
}
return 0;
}