Codeforces Round #805 (Div. 3)E.Split Into Two Sets

题目链接:https://codeforces.ml/contest/1702/problem/E

题目大意:

  每张牌上面有两个数字,现在有n张牌(n为偶数),问能否将这n张牌分成两堆,使得每堆牌中的数字不重复;

  因为需要每堆牌不重复,那牌中的数字必须满足:

  1.每个数字出现的次数刚好为2

  2.同一张牌上出现的数字不同

  

  因为每张牌上有两个数字,所以我们可以将每张牌连成一个环,然后对每张牌进行涂色,如果包含相同数字的牌被涂成了相同的颜色,

  说明无论如何都不可能分为两堆;

  

 1 # include<iostream>
 2 # include<bits/stdc++.h>
 3 using namespace std;
 4 # define int long long
 5 # define endl "\n"
 6 const int N = 2e5 + 10;
 7 vector<int> g[N],vec[N];
 8 bool vis[N];
 9 int col[N];
10     bool ok = true;
11 void dfs(int u){
12     vis[u] = 1;
13     for(auto v:g[u]){
14         if(!vis[v]){/*如果尚未涂色,那就涂成与上一张牌不同的颜色,因为每条边连的是包含相同数字的牌*/
15             col[v] = 1-col[u];
16             dfs(v);
17         }
18         else if(col[v] == col[u]) ok = false;
19     }
20 }
21 
22 void solve() {
23     int n;
24     ok = true;
25     cin>>n;
26     for(int i = 1;i <= n;++i)g[i].clear(),vec[i].clear(),vis[i] = 0;
27     for(int i = 1;i <= n;++i){
28         int a,b;
29         cin>>a>>b;
30         vec[a].push_back(i);
31         vec[b].push_back(i);/*记录每个数字在第几张牌上*/
32         if(a==b) ok = false;/*同一张牌上的数字不同*/
33     }
34     for(int i = 1;i <= n;++i) if(vec[i].size()!=2) ok =false;/*每个数字出现的次数刚好为2*/
35     if(!ok){
36         cout<<"NO"<<endl;
37         return;
38     }
39     for(int i = 1;i <= n;++i){
40         int u = vec[i][0],v = vec[i][1];
41         g[u].push_back(v);
42         g[v].push_back(u);/*将包含相同数字的牌连起来*//*例如:{1,2}->{2,3}->{3,5}*/
43     }
44     for(int i = 1;i <= n;++i){
45         if(!vis[i]){
46             col[i] = 1;/*涂色*/
47             dfs(i);
48         }
49     }
50     if(ok) cout<<"YES"<<endl;
51     else cout<<"NO"<<endl;
52     
53     
54 }
55 int tt;
56 signed main() {
57     ios::sync_with_stdio(false);
58     cin.tie(0);
59     cout.tie(0);
60     cin >> tt;
61     while (tt--)solve();
62 
63     return 0;
64 }
69 
70 
71 */

 

posted @ 2022-07-11 14:01  empty_y  阅读(150)  评论(0)    收藏  举报