• 染色法判定二分图 模板 题解《挑战程序设计竞赛》


    地址 https://www.acwing.com/problem/content/862/

    给定一个n个点m条边的无向图,图中可能存在重边和自环。

    请你判断这个图是否是二分图。

    输入格式

    第一行包含两个整数n和m。

    接下来m行,每行包含两个整数u和v,表示点u和点v之间存在一条边。

    输出格式

    如果给定图是二分图,则输出“Yes”,否则输出“No”。

    数据范围

    1n,m105

    输入样例:

    4 4
    1 3
    1 4
    2 3
    2 4
    

    输出样例:

    Yes

    基本模板

    遍历图 然后随机分配颜色 与该点相邻的点必须是另一种颜色

    模板代码

     1 #include <cstring>
     2 #include <iostream>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int N = 100010, M = 200010;
     8 
     9 int n, m;
    10 int h[N], e[M], ne[M], idx;
    11 int color[N];
    12 
    13 void add(int a, int b)
    14 {
    15     e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
    16 }
    17 
    18 bool dfs(int u, int c)
    19 {
    20     color[u] = c;
    21 
    22     for (int i = h[u]; i != -1; i = ne[i])
    23     {
    24         int j = e[i];
    25         if (!color[j])
    26         {
    27             if (!dfs(j, 3 - c)) return false;
    28         }
    29         else if (color[j] == c) return false;
    30     }
    31 
    32     return true;
    33 }
    34 
    35 int main()
    36 {
    37     scanf("%d%d", &n, &m);
    38 
    39     memset(h, -1, sizeof h);
    40 
    41     while (m -- )
    42     {
    43         int a, b;
    44         scanf("%d%d", &a, &b);
    45         add(a, b), add(b, a);
    46     }
    47 
    48     bool flag = true;
    49     for (int i = 1; i <= n; i ++ )
    50         if (!color[i])
    51         {
    52             if (!dfs(i, 1))
    53             {
    54                 flag = false;
    55                 break;
    56             }
    57         }
    58 
    59     if (flag) puts("Yes");
    60     else puts("No");
    61 
    62     return 0;
    63 }
    View Code

    自己代码

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <string>
     5 
     6 
     7 using namespace std;
     8 
     9 /*
    10 输入格式
    11 第一行包含两个整数n和m。
    12 
    13 接下来m行,每行包含两个整数u和v,表示点u和点v之间存在一条边。
    14 
    15 输出格式
    16 如果给定图是二分图,则输出“Yes”,否则输出“No”。
    17 
    18 数据范围
    19 1≤n,m≤105
    20 输入样例:
    21 7 7
    22 1 3
    23 1 4
    24 2 3
    25 2 4
    26 5 6
    27 6 7
    28 5 7
    29 输出样例:
    30 No
    31 */
    32 
    33 const int N = 100010, M = 200010;
    34 
    35 int n, m;
    36 
    37 vector<vector<int>> uv(100010);
    38 
    39 vector<int> colorr(100010);
    40 
    41 string ret;
    42 
    43 void dfs(int idx,int color) {
    44     if (idx > n || ret == "No" ) {
    45         return;
    46     }
    47 
    48     colorr[idx] = color;
    49     
    50     //变色
    51     color = color % 2 + 1;
    52     for (int i = 0; i < uv[idx].size(); i++) {
    53         //与该点相邻的点 都染上其他颜色
    54         int coloridx = uv[idx][i];
    55         //颜色冲突 则直接返回
    56         if (colorr[coloridx] != 0 && colorr[coloridx] != color)
    57         {
    58             ret = "No";
    59             return;
    60         }
    61         if(ret.empty() && colorr[coloridx] == 0)
    62             dfs(coloridx, color);
    63     }
    64 
    65 
    66     return;
    67 }
    68 
    69 
    70 int main()
    71 {
    72     cin >> n >> m;
    73 
    74     for (int i = 0; i < m; i++) {
    75         int a; int b;
    76         cin >> a >> b;
    77         uv[a].push_back(b);
    78         uv[b].push_back(a);
    79     }
    80     /*for(int i= 1;i < n;i++)
    81         dfs(i,1);*/
    82 
    83     for (int i = 1; i <= n; i++) {
    84         if (ret == "No") break;
    85         if (colorr[i] != 0)  continue;
    86         dfs(i, 1);
    87     }
    88 
    89     if (ret.empty())  ret = "Yes";
    90     cout << ret << endl;
    91 
    92 
    93     return 0;
    94 }
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    jQuery文件上传插件Uploadify(转)
    最简单易懂的SpringCloudSleuth教程
    微信协议简单调研笔记
    Base64 image
    javascript身份证号码验证
    基于微信的产品设计01:注册登录及账号体系设计
    android端 socket长连接 架构
    win7管理工具不可用
    http和socket之长连接和短连接区别
    Socket 长连接与短连接,心跳
  • 原文地址:https://www.cnblogs.com/itdef/p/12017792.html
Copyright © 2020-2023  润新知