題意:給n個互不相同的數以及兩數a,b,有兩個類a,b。
對於n個數中的任意數x,若x在a中,a-x也必在a中;若x在b中,b-x也必在b中。試問這組數滿足上述條件否?若滿足則輸出yes,並說明第i個數屬於第幾類(類別用0,1表示);若不滿足,則輸出no。
樣例:4 5 9 yes
2 3 4 5 0 0 1 1
3 3 4 no
1 2 4
題解:該題可用並查集解,由於x的範圍過大,先用map離散化一下。
我們將類a的其中乙個葉子定為n+1,類b其中乙個葉子定為n+2。
對於任意的c[i]:
若a-c[i]存在,則c[i]和a-c[i]必在同一類中但不知道在哪個類中。
很好想,若c[i]在a中,則a-c[i]必須也在a中和c[i]配對;若c[i]在b中,a-c[i]若在a中,則不存在與其配對的c[i](n個數各不相同),則該情況不可能存在,即a-c[i]也在b中。
若a-c[i]不存在,則c[i]只可能在b中。
對於b-c[i]存在的討論同理,若b-c[i]存在,則其與c[i]在同一集合,若不存在,則c[i]可能在a中。
若滿足條件,a,b兩棵樹應該無交集,即find(n+1)!=find(n+2)。對於每個c[i],只需要看find(c[i])等於find(n+1)還是find(n+2)從而得出其在哪個類中。
若不滿足,直接輸出no即可。
滿足條件時:
ac**:
1 #include2 #include3 #include4 #include5 #include6 #include7 #include
8 #include9 #include10
#define inf int(0x3f3f3f3f)
11#define pi acos(-1.0)
12#define lson l,m,rt<<1
13#define rson m+1,r,rt<<1|1
14#define ll long long
15#define maxn 100005
16using
namespace
std;
1718
19int
n,a,b;
20int
c[maxn];
21int
fa[maxn];
2223 mapmp;
2425
void
init()
2630
31int findfa(int
x)32
3839
void unit(int x,int
y)40
4748
49int
main()
5058
59init();
60for(int i=1;i<=n;i++)
6172
73//
若a-c[i]與b-c[i]都不存在 則ab樹相連了
7475
if(findfa(n+1)==findfa(n+2
))76
8081 printf("
yes\n");
8283
for(int i=1;i<=n;i++)
8493
94return0;
95 }
分類並查集 並查集的複習
動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n編號。每個動物都是a,b,c中的一種,但是我們並不知道它到底是哪一種。有人用兩種說法對這n個動物所構成的食物鏈關係進行描述 第一種說法是 1 x y 表示x和y是同類。第二種說法是 2 ...
並查集 並查集
本文參考了 挑戰程式設計競賽 和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 ...
分類討論與並查集 Homework
如果y yy的取值比較小,我們可以每一次都對讀入都直接用陣列標記。如果y yy的取值比較大的話,我們可以查詢1 t 1 t1 t的最小值,t 1 t 1t 1 2 t2 t 2 t的最小值等等。最小值可以利用並查集來維護,倒著刪除數字即可。具體實現的話讓每乙個數i ii聯想i 1 i 1i 1,如果...