並查集的擴充套件域

2021-09-25 06:10:22 字數 1095 閱讀 7227

核心思想:

fa[a]儲存與a同類的

fa[a+1 * n]儲存與a發生第一類關係的

fa[a+2 * n]儲存與a發生第二類關係的

fa[a+3 * n]儲存與a發生第三類關係的

分析將並查集中儲存節點關係的f陣列擴大2倍,1~n表示朋友,n + 1~2 * n表示敵人。

那麼對於x,y,如果x和y是朋友,直接合併,如果x和y是敵人,則y+n是y的敵人,x和y+n是朋友,所以合併x和y+n,同理,合併y和x+n。

#include#includeusing namespace std;

#define m 5000 + 10

int f[m << 1];

int find(int x)

void merge(int x,int y)

int main()

else

} int ans = 0;

for(int i = 1; i <= n; i++)

if(f[i] == i) ans++;

printf("%d\n",ans);

return 0;

}

分析同上一道題一樣,開闢多乙個n空間來儲存x的補集,即不包含x的集合,將衝突按值從大到小排序,這樣一開始就可以就將大的衝突分開,直到發生第一次衝突,即衝突的雙方在同一集合中,這時找到的衝突值就是不可避免的最大的衝突值。

#include#include#includeusing namespace std;

#define n 20000 + 10

#define m 100000 + 10

int f[n << 1];

struct edge

} e[m];

int find(int x)

void merge(int x,int y)

int main()

merge(y + n,x);//y+n表示y的補集

merge(x + n,y);//x+n表示x的補集

} printf("0\n");

return 0;

}

True Liars 擴充套件域並查集

傳送門 每個點拆成兩個,表示好人或壞人 我們合併集合後,發現存在幾組對立的集合 也就是說這個集合和與它對立的集合只能選乙個 我們用rt1 i rt2 i 表示第i個集合 和 與第i個集合對立的集合 cnt1,cnt2表示該集合好人的個數 用f i j 表示到第i個集合,好人為j的方案數 同時記錄fr...

詳解 並查集高階技巧 加權並查集 擴充套件域並查集

可以理解為使用陣列實現的樹形結構,只儲存了每個節點的父節點 前驅 功能為 合併兩個節點 及其所在集合 查詢節點所屬集合的代表節點 可以理解為根節點 以6個元素為例 編號0到5 把0單獨劃分為乙個集合 把1,2,3,4劃分為乙個集合 把5單獨劃分為乙個集合。n個元素的並查集,只需要乙個容量為n的陣列f...

食物鏈 並查集擴充套件域

食物鏈 2001年noi全國競賽 時間限制 3 s 空間限制 64000 kb 題目描述 description 動物王國中有三類動物 a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。...