P8686 [蓝桥杯 2019 省 A] 修改数组


备赛蓝桥杯和icpc的习题:
一道并查集的题目

> #include<iostream>
> #include<vector>
> #include<algorithm>
> #include<math.h>
> #include<string>
> #include<string.h>
> #include<iomanip>
> #include<map>
> #include<queue>
> using namespace std;
> typedef long long ll;
> int n;//n个整数
> ll mp[100010] = { 0 };//存储初始数据
> ll s[100010] = { 0 };//存储i对应的终点:s[i]
> void init()//初始化
> {
> 	for (ll i = 1; i <= 100000; i++)s[i] = i;
> }
> ll merge_(ll i)//合并,同时路径压缩
> {
> 	if (s[i] != i)s[i]=merge_(s[i]);
> 	return s[i];
> }
> int main()
> {
> 	cin >> n;
> 	for (int i = 1; i <= n; i++)cin >> mp[i];
> 	init();
>
> 	for (int i = 1; i <= n; i++)
> 	{
> 		ll th = mp[i];//记录前驱,修改的节点,因为不记录的话会被下一行的mp[i]更新
> 		mp[i] = s[merge_(mp[i])];//所有都要修改,沿途之处不一定是终点,只有遍历到i=s[i]时才正确
>  		s[merge_(mp[i])]++;//增加1,使得下一个重复的点可以增加
> 		merge_(th);//合并,路径压缩
> 	}
> 	for (int i = 1; i <= n; i++)cout << mp[i] << ' ';
> 	return 0;
> }

debug了10几分钟,难绷。

posted on 2024-03-07 20:49  WHUStar  阅读(3)  评论(0编辑  收藏  举报