ds 12.3 箱子里的木块

来源:互联网 发布:中国历代疆域图软件 编辑:程序博客网 时间:2024/05/05 23:38


/***************Problem from :dsProblem describe:    deal-way:    暴力解会超时这题使用公式 :  size - dis - 1  集合总和-当前点到达首元素的距离-本身 = 当前点底下的点的总数 使用并查集算法实现 data:2016.12.4****************/#include<iostream>#include<cstdlib>#include<cstdio>#include<algorithm>#include<cmath>#include<map>#include<stack>#include<queue>#include<ctime>#include<cstring>#include<vector>#include<string>#define ll __int64#define inf 0x3f3f3f3f3fusing namespace std;int Fa[30005], size[30005];int dis[30005];void init(int n) //初始化各数据 {for(int i=1; i<n+4; i++){Fa[i]=i;dis[i]=0;size[i]=1;}return ;}int Find(int x){if( Fa[x] == x ) return x;else{int t=Fa[x]; Fa[x] = Find(Fa[x]); //继续递归查找 dis[x] += dis[t];//更新该点到达原元素的距离 }return Fa[x];}void UnitSet(int x, int y){int x_Fa = Find(x);int y_Fa = Find(y);if(x_Fa == y_Fa) return ;Fa[y_Fa] = x_Fa;//合并 集合dis[y_Fa] = size[x_Fa]; //被吞并的集合的首元素到达整合后的集合的首元素等于原先集合的大小 size[x_Fa] +=  size[y_Fa];//更新合并后的集合的size return ;}int main(){//  freopen("in.txt","r",stdin);//  freopen("out.txt","w",stdout);int i, n, T, ans=0, x, y;char c;scanf("%d %d", &n, &T);init(n);while(T--){scanf(" %c", &c);if(c=='M'){scanf("%d %d", &x, &y);UnitSet(x, y);}else if(c=='C'){scanf("%d", &x);int x_fa = Find(x);printf("%d\n", (size[x_fa] - dis[x]-1));}}return 0;}


0 0
原创粉丝点击