核心思想:
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中的一種,但是我們並不知道它到底是哪一種。...