数据结构 - 启发式合并

Posted rr-jin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 - 启发式合并相关的知识,希望对你有一定的参考价值。

  定义:将两个数据结构合并时,应将小的数据结构中的元素一个一个分别插入大的数据结构。


顺便写了一道“简单”题 —— 梦幻布丁可坑死我了是我太弱了)

现在回过头来这道题真的不难,我只是栽到以前挖的坑里去了(链表没学好)

这告诉我们一个道理 —— 千万不要边走边挖坑啊,有坑赶紧填!

我jio得这篇代码注释真的很良心(因为几乎没有人给这么简单的代码标注释)

好了...... 笔者叨叨叨正式结束

 

  1.    颜色一定是单调不增,段数一定是单调不增的,可以一边修改一边 ans--
  2.       用链表维护每一个颜色的下标,启发式合并,每次取出较小的,如果某个位置的前面或后面原来不同改颜色后相同了就 ans--

——摘自大米饼

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #define N 100010
 4 #define M 1000010
 5 using namespace std;
 6 int n,m,ans;
 7 int c[N],next[N],ft[M],head[M],s[M],st[M];
 8 //c[i]表示第i个数字的颜色
 9 //ft[i]第i种颜色为 ft[i]
10 //head[i]第 i种颜色的表头,next[i]记下一个
11 //s[i]第 i种颜色的个数
12 //st[i]第 i种颜色的首位置 
13 int read()
14     int x=0,f=1; char c=getchar();
15     while(c<0||c>9) if(c==-) f=-1; c=getchar();
16     while(c>=0&&c<=9) x=x*10+c-0,c=getchar();
17     return x*f;
18 
19 void solve(int a,int b)
20     for(int i=head[a];i;i=next[i])     //遍历每个颜色为 a的元素 
21         if(c[i+1]==b) ans--;        //更改后的颜色 与 右邻颜色相同
22         if(c[i-1]==b) ans--;        //更改后的颜色 与 左邻颜色相同
23     
24     for(int i=head[a];i;i=next[i]) c[i]=b;    // 改变颜色 a->b  head[a]==b 
25     next[st[a]]=head[b]; head[b]=head[a];     // a(内部实际颜色已改变)合并到 b上
26     s[b]+=s[a];            //b颜色的个数  累加上  a(已改变为 b)的个数 
27     head[a]=st[a]=s[a]=0;        //有关 a  清零 
28 
29 int main()
30 
31     n=read(),m=read();
32     for(int i=1;i<=n;i++)
33         c[i]=read();
34         ft[c[i]]=c[i];
35         if(c[i]!=c[i-1]) ans++;
36         if(!head[c[i]]) st[c[i]]=i;
37         s[c[i]]++; next[i]=head[c[i]]; head[c[i]]=i;
38         //这个赋值法就是这样,和邻接表一个道理(一直不太会,因为会打就一直咕着),一开始折磨死我了,还好没有放弃。
39         //我是带了一组简单的数据模拟了一遍(我太弱了),现在看多了就好多了 ,加油 ^_^ 
40     
41     for(int i=1;i<=m;i++)
42         int a,b,x=read();
43         if(x==2) printf("%d\n",ans);
44         else
45             a=read(),b=read();
46             if(a==b) continue;        //改变为相同颜色=不变 
47             if(s[ft[a]]>s[ft[b]]) swap(ft[a],ft[b]);    //保证 小的(a)合并进大的(b) 
48             a=ft[a],b=ft[b];    // ft[x] 用于维护实际颜色(x)
49             if(s[a]==0) continue;    // 没有 a的颜色 
50             solve(a,b);
51         
52     
53     return 0;
54 

 

以上是关于数据结构 - 启发式合并的主要内容,如果未能解决你的问题,请参考以下文章

启发式合并

学习笔记::启发式合并

数据结构 - 启发式合并

HDU6191 Query on A Tree (01字典树+启发式合并)

启发式合并

树上启发式合并/dsu on tree