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 }
  • 相关阅读:
    将一堆图片自适应页面排列
    用正则匹配富文本中的文本,并替换其内容
    实战
    从 defineProperty 到 Proxy
    CSS 实现蜂巢/六边形图集
    Umi 小白纪实(三)—— 震惊!路由竟然如此强大!
    无题
    贺文
    模型可解释性方法--lime
    多模态融合注记
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4002340.html
Copyright © 2011-2022 走看看