分類並查集 並查集的複習

2021-08-29 20:22:26 字數 2498 閱讀 8725

動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b, b吃c,c吃a。 

現有n個動物,以1-n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。 

有人用兩種說法對這n個動物所構成的食物鏈關係進行描述: 

第一種說法是"1 x y",表示x和y是同類。 

第二種說法是"2 x y",表示x吃y。 

此人對n個動物,用上述兩種說法,一句接一句地說出k句話,這k句話有的是真的,有的是假的。當一句話滿足下列三條之一時,這句話就是假話,否則就是真話。 

1) 當前的話與前面的某些真的話衝突,就是假話; 

2) 當前的話中x或y比n大,就是假話; 

3) 當前的話表示x吃x,就是假話。 

你的任務是根據給定的n(1 <= n <= 50,000)和k句話(0 <= k <= 100,000),輸出假話的總數。 

input

第一行是兩個整數n和k,以乙個空格分隔。 

以下k行每行是三個正整數 d,x,y,兩數之間用乙個空格隔開,其中d表示說法的種類。 

若d=1,則表示x和y是同類。 

若d=2,則表示x吃y。

output

只有乙個整數,表示假話的數目。

sample input

100 7

1 101 1

2 1 2

2 2 3

2 3 3

1 1 3

2 3 1

1 5 5

sample output

3
我們先回顧一下並查集的基本操作

for(int i=1;i<=n;i++) father[i]=i;//令結點等於i,father[i]也可以等於-1
遞推**

int findfa(int x)

}

遞迴**

int findfa(int x)
void union(int a,int b)
遞推的壓縮

int findfa(int x)

while(a!=father[a])

return x;

}

遞迴的壓縮

int findfa(int v)

}

以上是最基本的並查集操作,那我們再來分析一下這道題。

我們首先要知道,題目是讓我們求關係是否正確,而不是求兩兩之間的關係,我們就可以根據有無關係來進行分類。有關係的就放到乙個並查集中去,沒有的就不用管,再在這個並查集中去驗證關係是否正確。

為了關係的簡化,我們將並查集中的所有關係進行路徑壓縮,每個點只與根節點判斷關係,這樣操作是最省時間的。

為了表達關係,我們開乙個r【】陣列,用來存p[x]->x的關係,

我們設 r[x]=0, 就是只p[x]與x同類

r[x]=1,  p[x]吃掉x

r[x]=2, x吃掉p[x]

現在最難的就是關係的更新

我們假設 p[x]吃x x吃y 那麼y和p[x]的關係是什麼呢?          很顯然,y吃p[x], 食物鏈的關係 p[x]->x->y->p[x]。

我們現在分開寫 p[x]->y=p[x]->x+x->y; 是不是像向量形式(其實我是看的大佬的博文)我們繼續驗證 r[y]=r[x]+1=2 確實是y吃p[x]

(因為此時x與y的關係已知,y的父節點就是x的父節點p[x]),知道這個後,我們就可進行實現了。

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define  ll long long

#define ull unsigned long long

#define mod 1000000007

#define inf 0x7ffffff

#define mem(a,b) memset(a,b,sizeof(a))

using namespace std;

const int n=50005;

int p[n],r[n];

int findfa(int x)

return p[x];

}int union(int d,int x,int y)

p[fay]=fax;

r[fay]=(r[x]+d-1+3-r[y])%3;//這裡找rootx->rooy=rootx->x+x->y+y->rooty 注意符號

return 0;

}int main()

if(union(d,x,y)) cot++;

}printf("%d\n",cot);

return 0;

}

並查集複習

定義陣列 fa x 表示 x 的父親 操作之前先要初始化每乙個節點的父親為自己 for int i 1 i n i fa i i 並查集基本操作 查詢,合併 查詢 查詢元素所在集合 int query int x 路徑壓縮 int query int x 遞迴版 int query int x 合併...

並查集 並查集

本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...

並查集入門(普通並查集 帶刪除並查集 關係並查集)

什麼是並查集?通俗易懂的並查集詳解 普通並查集 基礎並查集 例題 題解 how many tables problem description lh boy無聊的時候很喜歡數螞蟻,而且,還給每乙隻小螞蟻編號,通過他長期的觀察和記錄,發現編號為i的螞蟻會和編號為j的螞蟻在一起。現在問題來了,他現在只有...