zoj 2833 Friendship(并查集)

嘻嘻。并查集的应用。

 

给你N个人,M种操作,M A B 是使A B 成为朋友,Q A是输出A的朋友数。朋友是可以传递的,比如A B,B C是朋友,那么A C也是朋友。

 

以前一直觉得并查集挺难理解的。这题开始我写的代码很繁琐,找他们公共的祖先,分了4种情况= =。

 

TLE ,WA之后,觉得太麻烦了,就直接查祖先,比较祖先,代码改得很简短了。依旧TLE。好吧。

 

后来加了两句话,不光把祖先相连,把判断的那个数的pre变成祖先,500+MS过了。

 

#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> #define MAX 100010 using namespace std; int pre[MAX]; int num[MAX]; void init() { int i; for(i=0; i<MAX; i++) { num[i] = 1; pre[i] = i; } } int find(int x) { while( x != pre[x] ) x = pre[x]; return x; } int main() { int n,m,x,y,out,a,b,blank = 0,ind = 1; char ch; while( scanf("%d%d",&n,&m) != EOF && n ) { if( blank ) printf("/n"); blank = 1; init(); printf("Case %d:/n",ind++); while( m-- ) { getchar(); scanf("%c",&ch); if( ch == 'M' ) { scanf("%d %d",&a,&b); x = find(a); y = find(b); pre[a] = x; pre[b] = y; // Magic~~~Save time~ if( x == y ) continue; else { pre[y] = x; num[x] += num[y]; } continue; } if( ch == 'Q') { scanf("%d",&out); printf("%d/n",num[find(out)]); } } } return 0; }

你可能感兴趣的:(c)