(并查集+路径压缩) hdu 2818

Building Block

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3352    Accepted Submission(s): 1003

Problem Description

John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:

M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command. 
C X : Count the number of blocks under block X

You are request to find out the output for each C operation.

Input

The first line contains integer P. Then P lines follow, each of which contain an operation describe above.

Output

Output the count for each C operations in one line.

Sample Input

6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

Sample Output

1
0
2

Source

2009 Multi-University Training Contest 1 - Host by TJU

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define maxn 300100
int n,fa[maxn],num[maxn],under[maxn];
char s[5];
int find(int x)
{
      if(x==fa[x])
            return x;
      int k=fa[x];
      fa[x]=find(fa[x]);
      under[x]+=under[k];
      return fa[x];
}
void Union(int x,int y)
{
      int fx,fy;
      fx=find(x),fy=find(y);
      if(fx!=fy)
      {
            under[fx]=num[fy];
            num[fy]+=num[fx];
            fa[fx]=fy;
      }
}
int main()
{
      int x,y;
      while(scanf("%d",&n)!=EOF)
      {
            for(int i=0;i<=n;i++)
                  fa[i]=i,num[i]=1,under[i]=0;
            for(int i=0;i<n;i++)
            {
                scanf("%s",s);
                if(s[0]==‘M‘)
                {
                      scanf("%d%d",&x,&y);
                      Union(x,y);
                }
                else if(s[0]==‘C‘)
                {
                      scanf("%d",&x);
                      find(x);
                      printf("%d\n",under[x]);
                }
            }
      }
      return 0;
}

  

时间: 2024-10-12 03:32:01

(并查集+路径压缩) hdu 2818的相关文章

hdu 1558 线段相交+并查集路径压缩

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3457    Accepted Submission(s): 1290 Problem Description A segment and all segments which are connected with it compose a segment set.

HDU 3635 Dragon Balls(并查集--路径压缩拓展应用)

题目大意: 初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城市中. 现在又2种操作: T A B,表示把A球所在城市全部的龙珠全部转移到B城市.(第一次时,因为A球所在的城市只有一个球,所以只移动1个,如果有多个,则全部移动). Q A,表示查询A.要求得到的信息分别是:A现在所在的城市,A所在城市的龙珠数目,A转移到该城市移动的次数(如果没有移动就输出0) 思路:并查集,难点在于求龙珠的转移次数,可以在路径压缩的过程中沿着递归路径累加. //Accepted 1740 KB 5

并查集 路径压缩(具体解释)

拿HDU 1232举例. 题解: 首先在地图上给你若干个城镇.这些城镇都能够看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比方任意给你两个点,让你推断它们是否连通,或者问你整幅图一共同拥有几个连通分支,也就是被分成了几个互相独立的块.像畅通project这题,问还须要修几条路.实质就是求有几个连通分支.假设是1个连通分支,说明整幅图上的点都连起来了,不用再修路了.假设是2个连通分支,则仅仅要再修1条路,从两个分支中各选一个点,把它们连起来,那么全部的点都是

并查集 路径压缩(详解)

拿HDU 1232举例. 题解: 首先在地图上给你若干个城镇,这些城镇都可以看作点,然后告诉你哪些对城镇之间是有道路直接相连的.最后要解决的是整幅图的连通性问题.比如随意给你两个点,让你判断它们是否连通,或者问你整幅图一共有几个连通分支,也就是被分成了几个互相独立的块.像畅通工程这题,问还需要修几条路,实质就是求有几个连通分支.如果是1个连通分支,说明整幅图上的点都连起来了,不用再修路了:如果是2个连通分支,则只要再修1条路,从两个分支中各选一个点,把它们连起来,那么所有的点都是连起来的了:如果

并查集 路径压缩

使用并查集查找时,如果查找次数很多,那么使用朴素版的查找方式肯定要超时.比如,有一百万个元素,每次都从第一百万个开始找,这样一次运算就是10^6,如果程序要求查找个一千万次,这样下来就是10^13,肯定要出问题的. 这是朴素查找的代码,适合数据量不大的情况: int findx(int x){ int r=x; while(parent[r] !=r) r=parent[r]; return r;} 下面是采用路径压缩的方法查找元素: int find(int x) //查找x元素所在的集合,回

poj 2513 Colored Sticks(欧拉回路 并查集 路径压缩 字典树)(困难)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 32545   Accepted: 8585 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

并查集路径压缩与启发式合并

[程序清单] 初始化: for i:=1 to n do father[i]:=i; 因为每个元素属于单独的一个集合,所以每个元素以自己作为根结点. 寻找根结点编号并压缩路径: function getfather(v : integer) : integer; begin if father[v]=v then exit(v); father[v]:=getfather(father[v]); getfather:=father[v]; end; 合并两个集合: proceudre merge

snnu(1110) 传输网络 (并查集+路径压缩+离线操作)

1110: 传输网络 Time Limit: 3 Sec  Memory Limit: 512 MBSubmit: 43  Solved: 18[Submit][Status][Web Board] [Edit] Description Byteland国家的网络单向传输系统可以被看成是以首都Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的.现在他们开始在其他城市陆续建立了新的基站,命令“C x“代表在城市x建立了一个新的基站

poj1988Cube Stacking(并查集+路径压缩)

本题依然是并查集的应用,与上一个监狱的问题不同,本题计算的是距离,通过记录通往自己父节点距离的相对距离,与父节点到根节点(代表元素)的距离依次相加 路径压缩时每次都要更新节点. #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int maxn=30001; int p; struct { int fat