Peng Lv

毋意,毋必,毋固,毋我。 言必行,行必果。

导航

HDU 3635 Dragon Balls [并查集]

题意:有n颗龙珠分别顺序放在n个城市中,有两种操作

  (1)T A B:把A所在城市的所有龙珠转运到B所在的城市。

  (2)Q A :查询A所在的城市,所在城市的龙珠个数,A被转运了几次

思路:开始就是想用并查集做,但是处理细节很麻烦,每个节点记录被转运的次数,路径压缩时就可以修改节点,别的方法没想到...输入数据很多cin回超时。

#include <iostream>
#include
<cstdio>
#include
<algorithm>
#include
<memory.h>
#include
<cmath>
#include
<bitset>
#include
<queue>
#include
<vector>
#include
<map>
#include
<stack>
#include
<set>
#include
<list>
#include
<deque>
#include
<cstdlib>
#include
<cstring>
const int BORDER = (1<<20)-1;
const int MAXSIZE = 37;
const int MAXN = 20500;
const int INF = 0x3f3f3f3f;

#define CLR(x,y) memset(x,y,sizeof(x))
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))
#define REP(i,x,y) for(i=x;i<y;++i)

#define getbit(a,i) (a&(1<<i))
#define setbit(a,i) (a|(1<<i))

using namespace std;

int pre[MAXN],ct[MAXN],num[MAXN];
int ic,n,m;

int find_set(int x)
{
int root = x;
int tmp,tmp_c,t;
t
= 0;
while(pre[root]>=0)
{
root
= pre[root];
t
= t + ct[root];
}
ct[x]
+= t;
while(x!=root)
{
tmp
= pre[x];
tmp_c
= ct[tmp];
pre[x]
= root;
ct[tmp]
= t;
t
-= tmp_c;
x
= tmp;
}
return root;
}
void union_set(const int& root1,const int& root2)
{
if(num[root1] == 0)
return ;
num[root2]
+= num[root1];
num[root1]
= 0;
++ct[root1];
pre[root2]
+= pre[root1];
pre[root1]
= root2;
return ;
}

int init()
{
CLR(ct,
0);
CLR(pre,
-1);
return 0;
}
int input()
{
scanf(
"%d%d",&n,&m);
int i;
REP(i,
0,n+1)
num[i]
= 1;
return 0;
}
int work()
{
int i,a,b;
int pos,cnt,t;
int root1,root2;
char ch[3];
printf(
"Case %d:\n",ic);
++ic;
REP(i,
0,m)
{
scanf(
"%s",ch);
if(ch[0] == 'T')
{
scanf(
"%d %d",&a,&b);
root1
= find_set(a);
root2
= find_set(b);
union_set(root1,root2);
}
else
{
scanf(
"%d",&a);
pos
= find_set(a);
printf(
"%d %d %d\n",pos,num[pos],ct[a]);
}
}
return 0;
}
int main()
{
ic
= 1;
int tt;
scanf(
"%d",&tt);
while(tt--)
{
init();
input();
work();
}
return 0;
}

 

posted on 2010-09-22 08:56  Lvpengms  阅读(539)  评论(0编辑  收藏  举报