• AcWing 860. 染色法判定二分图


    本题链接 :活动 - AcWing

    题目:

    样例:

    输入
    1. 4 4
    2. 1 3
    3. 1 4
    4. 2 3
    5. 2 4

    输出
    Yes

    思路:

            根据题目意思,我们明确一下二分图的含义。

            二分图是图论中的一个重要概念。一个图被称为二分图,当且仅当能够将其所有顶点分割成两个互不相交的子集,使得每条边的两个顶点分别属于不同的子集。

            换句话说,对于一个二分图,可以把图中的顶点分成两组,使得同一组内的顶点之间没有边相连,而不同组内的顶点之间有边相连。

            通俗的讲,二分图就像是一个人群中的男女混合舞会,所有参与者可以分成两组:男生和女生。在这个舞会上,男生只和女生跳舞,而不和其他男生跳舞;女生也只和男生跳舞,而不和其他女生跳舞。没有两个男生或两个女生会成对跳舞。

            如果一个图是二分图,就意味着可以将所有的点分成两组,使得同一组内的点之间没有直接相连的边,而不同组内的点之间有直接相连的边。这种特性在很多实际问题中都有重要的应用。

            所以,我们可以用DFS或者BFS暴搜即可枚举出答案。

    代码详解如下:

    DFS法:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define endl '\n'
    8. #define int long long
    9. #define Yes puts("Yes")
    10. #define No puts("No")
    11. #define umap unordered_map
    12. #define All(x) x.begin(),x.end()
    13. #pragma GCC optimize(3,"Ofast","inline")
    14. #define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
    15. using namespace std;
    16. const int N = 2e6 + 10;
    17. int n,m;
    18. // 数组模拟链表
    19. vector<int>h(N,-1); // 链表头指针
    20. int e[N],ne[N],idx;
    21. inline void Add(int a,int b)
    22. {
    23. e[idx] = b,ne[idx] = h[a],h[a] = idx++;
    24. }
    25. int color[N]; // 记录是否染色
    26. // color 状态 0 表示未染色
    27. // 1 表示染黑色
    28. // 2 表示染白色
    29. bool DFS(int node,int inColor)
    30. {
    31. color[node] = inColor; // 将其染色
    32. // 枚举其相连的结点,查看是否染色
    33. for(int i = h[node];i != -1;i = ne[i])
    34. {
    35. int j = e[i]; // 取出相邻的结点
    36. // 如果相邻的结点没有染色
    37. if(!color[j])
    38. {
    39. // 我们将其染成当前结点的另一种颜色,其中如果出现冲突的染色,我们返回 false
    40. if(!DFS(j,3 - inColor)) return false;
    41. }else if(inColor == color[j]) return false;
    42. // 否则,如果相邻的结点已经染色了,并且出现与当前结点的颜色冲突,我们返回 false
    43. }
    44. return true; // 染色没有问题,返回 true
    45. }
    46. inline void solve()
    47. {
    48. cin >> n >> m;
    49. while(m--)
    50. {
    51. int a,b;
    52. cin >> a >> b;
    53. Add(a,b),Add(b,a); // 由于是无向图,所以双向相连
    54. }
    55. // 枚举每个结点查看是否染色
    56. for(int i = 1;i <= n;++i)
    57. {
    58. // 如果没有染色,那么我们将其染色
    59. if(!color[i])
    60. {
    61. // 如果出现冲突的染色,直接输出 No
    62. if(!DFS(i,1))
    63. {
    64. No;
    65. return ;
    66. }
    67. }
    68. }
    69. Yes; // 如果都符合二分图定义,输出 Yes
    70. }
    71. signed main()
    72. {
    73. // freopen("a.txt", "r", stdin);
    74. IOS;
    75. int _t = 1;
    76. // cin >> _t;
    77. while (_t--)
    78. {
    79. solve();
    80. }
    81. return 0;
    82. }

    最后提交:

    BFS法:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #define endl '\n'
    8. #define int long long
    9. #define Yes puts("Yes")
    10. #define No puts("No")
    11. #define umap unordered_map
    12. #define All(x) x.begin(),x.end()
    13. #pragma GCC optimize(3,"Ofast","inline")
    14. #define IOS std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
    15. using namespace std;
    16. const int N = 2e6 + 10;
    17. using PII=pair<int,int>;
    18. int n,m;
    19. // 数组模拟链表
    20. vector<int>h(N,-1); // 链表头指针
    21. int e[N],ne[N],idx;
    22. inline void Add(int a,int b)
    23. {
    24. e[idx] = b,ne[idx] = h[a],h[a] = idx++;
    25. }
    26. int color[N]; // 记录是否染色
    27. // color 状态 0 表示未染色
    28. // 1 表示染黑色
    29. // 2 表示染白色
    30. inline bool BFS()
    31. {
    32. queueq; // 存储需染色结点
    33. // 枚举每个结点
    34. for(int i = 1;i <= n;++i)
    35. {
    36. if(!color[i])
    37. {
    38. q.emplace(PII(i,1));
    39. // BFS 搜索
    40. while(q.size())
    41. {
    42. // 取出需染色的结点
    43. PII now = q.front();
    44. q.pop();
    45. // 获取数据
    46. int node = now.first;
    47. int inColor = now.second;
    48. color[node] = inColor; // 开始染色
    49. // 枚举相邻的结点,是否染色
    50. for(int i = h[node];i != -1;i = ne[i])
    51. {
    52. int j = e[i];
    53. if(!color[j])
    54. {
    55. q.emplace(PII(j,3 - inColor)); // 存储染色结点
    56. }else if(color[j] == inColor) return false;
    57. }
    58. }
    59. }
    60. }
    61. return true;
    62. }
    63. inline void solve()
    64. {
    65. cin >> n >> m;
    66. while(m--)
    67. {
    68. int a,b;
    69. cin >> a >> b;
    70. Add(a,b),Add(b,a); // 由于是无向图,所以双向相连
    71. }
    72. if(BFS()) Yes;
    73. else No;
    74. }
    75. signed main()
    76. {
    77. // freopen("a.txt", "r", stdin);
    78. IOS;
    79. int _t = 1;
    80. // cin >> _t;
    81. while (_t--)
    82. {
    83. solve();
    84. }
    85. return 0;
    86. }

    最后提交:

  • 相关阅读:
    int指令
    在Unity中如何设置设备的高、中、低配
    swift UI 和UIKIT 如何配合使用
    SpringBoot项目jar发布获取jar包所在目录路径
    【算法】排序——冒泡排序
    echart 仪表盘实现指针的渐变色及添加图片
    Leetcode70. 爬楼梯
    前缀和详解
    顺丰函证通API集成,无代码开发连接CRM和电商平台
    springboot专利申请服务平台毕业设计源码260839
  • 原文地址:https://blog.csdn.net/hacker_51/article/details/136315717