1. 程式人生 > >Codeforces 469 D. Two Sets (並查集)

Codeforces 469 D. Two Sets (並查集)

tails 表示 DC 思路 fin contest () %d HR

題目鏈接:Two Sets

題意:

  有n個數,要分成A、B兩組,要求如果x∈A則a-x∈A,如果x∈B則b-x∈B,問是否存在一種符合要求的分法。

題解:

  並查集,先增加兩個點表示A和B集合的根,對於一個數x,如果a-x存在就把x和a-x放一起,否則就將x和B的根相連,如果b-x存在就把x和b-x放一起,否則就將x和A的根相連,最後看一下A和B集合的根是否相連就可以判斷出有沒有解了,至於分法就看這個數是和A的根相連還是B的根相連了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAX_N = 1e5 + 9
; 4 int vec[MAX_N],vis[MAX_N]; 5 map<int,int> mp; 6 int N,M,x; 7 void init() 8 { 9 mp.clear(); 10 } 11 int find_f(int x) 12 { 13 if(x == vis[x]) return x; 14 return vis[x] = find_f(vis[x]); 15 } 16 int main() 17 { 18 int a,b; 19 while(cin>>N>>a>>b) 20 {
21 init(); 22 for(int i=1;i<=N;i++) 23 { 24 scanf("%d",&vec[i]); 25 mp[vec[i]] = i; 26 } 27 for(int i=0;i<=N+3;i++) vis[i] = i; 28 29 for(int i=1;i<=N;i++) 30 { 31 if(mp[a-vec[i]] == 0) vis[find_f(mp[vec[i]])] = find_f(N+2
); 32 else vis[find_f(i)] = find_f(mp[a-vec[i]]); 33 if(mp[b-vec[i]] == 0) vis[find_f(mp[vec[i]])] = find_f(N+1); 34 else vis[find_f(i)] = find_f(mp[b-vec[i]]); 35 } 36 if(find_f(N+1) == find_f(N+2)) cout<<"NO"<<endl; 37 else 38 { 39 cout<<"YES"<<endl; 40 for(int i=1;i<=N;i++) 41 { 42 //cout<<"...."<<find_f(i)<<endl; 43 int x = find_f(N+1); 44 int y = find_f(N+2); 45 if(find_f(i) == x) printf("0 "); 46 else printf("1 "); 47 } 48 cout<<endl; 49 } 50 } 51 return 0; 52 } 53 /* 54 70 416035 416023 55 70034 70322 345689 345965 345701 70046 345737 345713 70166 345821 70010 345749 345677 345725 69962 345869 70178 70310 345785 69998 70070 69974 70058 346001 70106 345953 70226 70154 345929 69950 70298 346049 70346 345989 70286 69986 345893 70082 70238 345797 70250 345833 70334 345845 70094 70118 70202 345977 70262 70274 70190 345941 346025 345761 345773 70142 70022 70130 345881 345917 70358 345905 345665 346013 346061 345809 345857 346037 346073 70214 56 57 58 */

轉載自:http://blog.csdn.net/m0_37729344/article/details/73605481

Codeforces 469 D. Two Sets (並查集)