洛谷P3377 (資料結構 左偏樹)

2021-09-26 11:19:30 字數 1172 閱讀 1151

題意:合併堆及刪除堆中最小元素。

思路:採用一般的二叉堆可以實現刪除操作,但是要合併的話就會爆,因此引進了左偏樹這個資料結構,可在logn時間內實現合併操作。

左偏樹的性質:

1.堆的性質

2.左子節點的距離大於右子節點的距離

正是利用這些性質實現堆的快速合併。

**如下:

(其中並查集的路徑壓縮會破壞掉樹的結構,因此在路徑壓縮後要將所有相鄰節點的父節點都置為當前的根節點)

#include#include#includeusing namespace std;

#define maxn 100050

int n,m;

int val[maxn],f[maxn],dis[maxn],ls[maxn],rs[maxn];

bool vis[maxn];

inline void ini()

//並查集的時候使用;

memset(vis,false,sizeof(vis));

memset(ls,0,sizeof(ls));//0表示為空節點;

memset(rs,0,sizeof(rs));

}int merge(int x,int y)

//其中一棵樹為空的時候的處理;

if((val[x]>val[y])||(val[x]==val[y]&&x>y))

//按照小根堆的方式,將權值大的樹並到權值小的樹的右子樹上;

rs[x]=merge(rs[x],y);//遞迴方式繼續合併;

if(dis[ls[x]]f[ls[x]]=f[rs[x]]=f[x]=x;

if(rs[x]==0)

else

return x;

}int del(int x)//刪除根節點;

int find(int x)//並查集;

int main()

for(i=1;i<=m;i++)

int fa=find(a);

int fb=find(b);

if(fa!=fb)

} else

int fa=find(a);

printf("%d\n",val[fa]);

del(fa);

} }

return 0;

}

洛谷 P3377 模板 左偏樹

題目描述 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 ...

P3377 左偏樹,模板)

題意 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 1並...

洛谷P3377 模板 左偏樹(可並堆)

題目描述 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 ...