zoukankan      html  css  js  c++  java
  • 染色法判断是否是二分图 hdu2444

    用染色法判断二分图是这样进行的,随便选择一个点,

    1.把它染成黑色,然后将它相邻的点染成白色,然后入队列

    2.出队列,与这个点相邻的点染成相反的颜色

    根据二分图的特性,相同集合内的点颜色是相同的,即

    但是如果这个图不是二分图,那么就会这样

    把与1相邻的点2,3染成白色,然后入队列,然后2出队列,要把与2相邻的点2,3染成黑色,但是都染过了,所以不用染色

    但是3的颜色应该与2相反(如果是二分图的话),可是没有相反,所以就不是二分图

      1 #include <stdio.h>
      2 #include <queue>
      3 #include <string.h>
      4 using namespace std;
      5 const int N = 300;
      6 struct Edge
      7 {
      8     int v,next;
      9 }g[N*N];
     10 int first[N*N];
     11 int color[N*N];
     12 int cy[N];
     13 bool vis[N];
     14 int e;
     15 int n,m;
     16 bool is_ ;
     17 void addEdge(int a, int b)
     18 {
     19     g[e].v = b;
     20     g[e].next =first[a];
     21     first[a] = e++;
     22 }
     23 bool bfs(int cur)//染色法,判断是否是二分图
     24 {//时间复杂度   邻居矩阵O(n*n)   邻接表 O(n+e)
     25     queue<int> q;
     26     q.push(cur);
     27     color[cur] = 1;
     28     while(!q.empty())
     29     {
     30         cur = q.front();q.pop();
     31         for(int i=first[cur]; i!=-1; i=g[i].next)
     32         {
     33             int v = g[i].v;
     34             if(color[v] == -1)
     35             {
     36                 color[v] = 1 - color[cur];
     37                 q.push(v);
     38             }    
     39             
     40             if(color[v] == color[cur])
     41                 return false;
     42         }
     43     }
     44     return true;
     45 }
     46 void dfs_color(int cur)
     47 {
     48     for(int i=first[cur]; i!=-1; i=g[i].next)
     49     {
     50         int v = g[i].v;
     51         if(color[v] == -1)
     52         {
     53             color[v] = 1 - color[cur];
     54             dfs_color(v);
     55         }
     56         else if(color[v] == color[cur])
     57             is_ = false;
     58         
     59     }
     60 
     61 }
     62 bool dfs(int cur)
     63 {
     64     for(int i=first[cur]; i!=-1; i=g[i].next)
     65     {
     66         int v = g[i].v;
     67         if(!vis[v])
     68         {
     69             vis[v] = true;
     70             if(cy[v]==-1 || dfs(cy[v]))
     71             {
     72                 cy[v] = cur;
     73                 return true;
     74             }
     75         }
     76     }
     77     return false;
     78 }
     79 int Match()
     80 {
     81     int ans = 0;
     82     memset(cy, -1, sizeof(cy));
     83     for(int i=1; i<=n; ++i)
     84     {
     85         memset(vis, 0, sizeof(vis));
     86         ans += dfs(i);
     87     }
     88     return ans;
     89 }
     90 int main()
     91 {
     92     freopen("in.txt","r",stdin);
     93     int a,b,i;
     94     while(scanf("%d%d",&n,&m)!=EOF)
     95     {
     96         memset(first, -1, sizeof(first));
     97         e = 0;
     98         for(i=0; i<m; ++i)
     99         {
    100             scanf("%d%d",&a,&b);
    101             addEdge(a,b);
    102             addEdge(b,a);
    103         }
    104         is_ = true;
    105         memset(color, -1, sizeof(color));
    106         for(i=1; i<=n; ++i)
    107         {
    108             if(color[i] == -1)
    109             {
    110                 color[i] = 1;
    111                 dfs_color(i);
    112             }
    113         }
    114         if(!is_)
    115             puts("No");
    116         else
    117         {
    118             printf("%d
    ",Match()/2);//没有把集合x,y分开,所以相当有2个最大匹配
    119         }
    120     }
    121 }
  • 相关阅读:
    html语法规范
    html页面基本结构
    HTML头部结构详解
    文件路径中 / 和 ./ 和 ../的区别
    实体符号
    利用JS修改style属性和添加元素类名(important)
    Less
    Eureka自我保护计算
    Eureka元数据
    EurekaServer源码分析
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4002340.html
Copyright © 2011-2022 走看看