• E. Split Into Two Sets(染色法判断二分图)


    Problem - 1702E - Codeforces

    波利卡普最近得到了一组n(数字n-偶数)的骨牌。每块多米诺骨牌包含1到n的两个整数。

    他能把所有的骨牌分成两组,使每组骨牌上的数字都不一样吗?每张多米诺骨牌必须正好进入两组中的一组。

    例如,如果他有4张多米诺骨牌:{1,4}、{1,3}、{3,2}和{4,2},那么波利卡普就能按要求把它们分成两组。第一组可以包括第一张和第三张骨牌({1,4}和{3,2}),第二组是第二张和第四张({1,3}和{4,2})。

    输入
    第一行包含一个整数t(1≤t≤104)--测试案例的数量。

    接下来是测试用例的描述。

    每个测试用例的第一行包含一个偶数整数n(2≤n≤2⋅105)--多米诺骨牌的数量。

    接下来的n行包含一对数字ai和bi(1≤ai,bi≤n),描述第i块多米诺骨牌上的数字。

    保证所有测试案例的n之和不超过2⋅105。

    输出
    对每个测试案例打印。

    如果有可能将n块多米诺骨牌分成两组,使每组多米诺骨牌上的数字不同,则为YES。
    如果不可能,则打印NO。
    你可以在任何情况下打印YES和NO(例如,字符串yEs、yes、Yes和YES将被识别为一个肯定的答案)。

    例子
    inputCopy
    6
    4
    1 2
    4 3
    2 1
    3 4
    6
    1 2
    4 5
    1 3
    4 6
    2 3
    5 6
    2
    1 1
    2 2
    2
    1 2
    2 1
    8
    2 1
    1 2
    4 3
    4 3
    5 6
    5 7
    8 6
    7 8
    8
    1 2
    2 1
    4 3
    5 3
    5 4
    6 7
    8 6
    7 8
    输出拷贝

    拒绝




    备注
    在第一个测试案例中,多米诺骨牌可以被划分如下。

    第一组骨牌:[{1,2},{4,3}] 。
    第二组骨牌:[{2,1},{3,4}] 。
    换句话说,在第一组中,我们采取数字为1和2的骨牌,在第二组中,我们采取数字为3和4的骨牌。
    在第二个测试案例中,没有办法将多米诺骨牌分成两组,其中至少有一组会包含重复的数字。

    题解:
    根据例子我们发现

    将每一个骨牌看做双向边连接, 如样例5

    2 1
    1 2
    4 3
    4 3
    5 6
    5 7
    8 6
    7 8
    连完后建成的图为 {1,2}-{2,1}, {3,4}-{3,4}, {5,6}-{6,8}-{8,7}-{7,5}三个环 不难发现当环是偶数环时候, 我们可以隔着取放在一个集合里面, 如 {5,6}-{6,8}-{8,7}-{7,5}, 取{5,6},{8,7}放在一个集合, 其他两个放在另一个集合(即构建出一个二分图), 这样取两个集合中是不会出现重复的, 而若出现奇数环时, 取牌必定会有重复, 所以建完图后, 判断是否存在奇数环即可.

     

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<string>
    5. #include<map>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. #define int long long
    10. //1 1 3 3 3
    11. vector<int> p[200050];
    12. int n;
    13. map<int,int> vis;
    14. map<int,int> st;
    15. int dfs(int u,int x)
    16. {
    17. st[u] = x;
    18. for(int i = 0;i < p[u].size();i++)
    19. {
    20. int j = p[u][i];
    21. if(!st[j])
    22. {
    23. if(!dfs(j,3-x))
    24. {
    25. return 0;
    26. }
    27. }
    28. else if(st[j] == x)
    29. {
    30. return 0;
    31. }
    32. }
    33. return 1;
    34. }
    35. void solve()
    36. {
    37. cin >> n;
    38. vis.clear();
    39. st.clear();
    40. for(int i = 1;i <= n;i++)
    41. {
    42. p[i].clear();
    43. }
    44. int f = 0;
    45. for(int i = 1;i <= n;i++)
    46. {
    47. int a,b;
    48. cin >> a >> b;
    49. if(a == b)
    50. {
    51. f = 1;
    52. }
    53. vis[a]++,vis[b]++;
    54. if(vis[a]>2||vis[b] > 2)
    55. {
    56. f = 1;
    57. }
    58. p[a].push_back(b);
    59. p[b].push_back(a);
    60. }
    61. if(f)
    62. {
    63. cout<<"NO\n";
    64. return ;
    65. }
    66. for(int i = 1;i <= n;i++)
    67. {
    68. if(!st[i])
    69. {
    70. if(!dfs(i,1))
    71. {
    72. cout<<"NO\n";
    73. return ;
    74. }
    75. }
    76. }
    77. cout<<"YES\n";
    78. }
    79. signed main()
    80. {
    81. int t = 1;
    82. cin >> t;
    83. while(t--)
    84. {
    85. solve();
    86. }
    87. }
    88. //2 5
    89. //3
    90. //9 7
    91. //2 3 4 3

  • 相关阅读:
    【Linux】虚拟机部署与发布J2EE项目(Windows版本)
    1. 云计算简介
    启动Java应用的黑魔法:初始化性能解密@PostConstrut,InitialzingBean,init-method,BeanPostProcessor
    HEC-RAS 1D/2D水动力与水环境模拟教程
    Kubernetes(k8s)CNI(Calico)网络模型原理
    postman在ubuntu下报gpu-disable
    强强联合:OpenFeign 整合 Sentinel
    并发编程六 并发工具包 CountDownLatch&Semaphore应用与原理
    729. 我的日程安排表 I :「模拟」&「线段树(动态开点)」&「分块 + 位运算(分桶)」
    「SpringBoot」09 原理解析
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/128003889