• 交叉染色法判断二分图


    题目链接:传送门

    题目大意:给你一副无向联通图,判断是不是二分图

    题目思路:交叉染色法

        下面着重介绍下交叉染色法的定义与原理

        首先任意取出一个顶点进行染色,和该节点相邻的点有三种情况:

              1.未染色    那么继续染色此节点(染色为另一种颜色)

              2.已染色但和当前节点颜色不同      跳过该点

              3.已染色并且和当前节点颜色相同       返回失败(该图不是二分图)

        下面在拓展两个概念:

         (1) 如果一个双连通分量内的某些顶点在一个奇圈中(即双连通分量含有奇圈),那么这个双连通分量的其他顶点也在某个奇圈中;

         第一个条件的证明:我们假设有一个奇圈,因为是点双,没有割点,必然有紧挨着的圈,假设这个是偶数圈,则,这个偶数圈必然能和原来的奇圈组成新的奇圈(因为:新的圈=(奇数圈-k)+(偶数圈-k)=奇数+偶数-偶数=奇数,k是共同边上的点数

         (2) 如果一个双连通分量含有奇圈,则他必定不是一个二分图。反过来也成立,这是一个充要条件。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <cstring>
     7 #include <stack>
     8 #include <cctype>
     9 #include <queue>
    10 #include <string>
    11 #include <vector>
    12 #include <set>
    13 #include <map>
    14 #include <climits>
    15 #define lson root<<1,l,mid
    16 #define rson root<<1|1,mid+1,r
    17 #define fi first
    18 #define se second
    19 #define ping(x,y) ((x-y)*(x-y))
    20 #define mst(x,y) memset(x,y,sizeof(x))
    21 #define mcp(x,y) memcpy(x,y,sizeof(y))
    22 #define Min(x,y) (x<y?x:y)
    23 #define Max(x,y) (x>y?x:y)
    24 using namespace std;
    25 #define gamma 0.5772156649015328606065120
    26 #define MOD 1000000007
    27 #define inf 0x3f3f3f3f
    28 #define N 5005
    29 #define maxn 10005
    30 typedef long long LL;
    31 typedef pair<int,int> PII;
    32 
    33 int pic[200][200];
    34 int vis[200],n,m;
    35 
    36 inline void init(){
    37     mst(vis,-1);
    38     mst(pic,0);
    39 }
    40 
    41 int dfs(int x,int c){
    42     if(vis[x]!=-1&&vis[x]==c)return 0;
    43     vis[x]=c;
    44     for(int i=0;i<n;++i){
    45         if(pic[x][i]){
    46             if(vis[i]==-1)
    47                 dfs(i,c^1);
    48             else if(vis[i]==c)return 0;
    49         }
    50     }
    51     return 1;
    52 }
    53 
    54 int main(){
    55     int i,j,group,Case=0,x,y;
    56     while(scanf("%d",&n)!=EOF&&n){
    57         scanf("%d",&m);
    58         init();
    59         if(n==0)break;
    60         while(m--){
    61             scanf("%d%d",&x,&y);
    62             pic[x][y]=pic[y][x]=1;
    63         }
    64         if(dfs(0,0))printf("BICOLORABLE.
    ");
    65         else printf("NOT BICOLORABLE.
    ");
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    php逻辑操作符中&和&&的异同
    Web性能压力测试工具之WebBench详解
    Entity Framework加载相关实体——延迟加载Lazy Loading、贪婪加载Eager Loading、显示加载Explicit Loading
    EF中的贪婪加载和延迟加载(懒加载)
    WCF中的数据契约(DataContract)
    无废话WCF入门教程六[一个简单的Demo]
    无废话WCF入门教程五[WCF的通信模式]
    无废话WCF入门教程四[WCF的配置文件]
    无废话WCF入门教程三[WCF的宿主]
    无废话WCF入门教程二[WCF应用的通信过程]
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5524776.html
Copyright © 2020-2023  润新知