zoukankan      html  css  js  c++  java
  • Graph Coloring I(染色)

    Graph Coloring I

    https://www.nowcoder.com/acm/contest/203/J

    题目描述

    修修在黑板上画了一些无向连通图,他发现他可以将这些图的结点用两种颜色染色,满足相邻点不同色。
    澜澜不服气,在黑板上画了一个三个点的完全图。修修跟澜澜说,这个图我能找到一个简单奇环。
    澜澜又在黑板上画了一个n个点m条边的无向连通图。很可惜这不是一道数数题,修修做不出来了。
    澜澜非常得意,作为一位毒瘤出题人,有了好题当然要跟大家分享,于是他把这道题出给你做了。

    输入描述:

    第一行两个整数n,m (1≤ n,m≤ 3*10
    5
    ),接下来m行每行两个整数a
    i
    ,b
    i
    表示一条边 (1≤ a
    i
    ,b
    i
    ≤ n)。
    保证图连通,并且不存在重边和自环。

    输出描述:

    如果你能把图二染色,第一行输出0,第二行输出n个整数
    表示每个点的颜色 (0≤ x
    i
    ≤ 1)。如果有多种合法方案,你可以输出任意一种。
    如果你能找到一个简单奇环,第一行输出环长k,第二行输出k个整数
    表示环上结点编号 (1≤ y
    i
    ≤ n),你需要保证y
    i
    和y
    i+1
    之间有边,y
    1
    和y
    n
    之间有边。如果有多种合法方案,你可以输出任意一种。
    如果两种情况都是可行的,你只需要输出任意一种。
    如果两种情况都是不可行的,请输出一行一个整数-1。
    示例1

    输入

    3 2
    1 2
    1 3

    输出

    0
    0 1 1
    示例2

    输入

    3 3
    1 2
    1 3
    2 3

    输出

    3
    1 2 3

    用dfs边搜索边染色,看看有没有相邻的节点有相同的颜色,并判断是否有奇环(如果相邻的节点有相同的颜色就说明存在奇环),都不满足的话就输出-1

     1 #include<iostream>
     2 #include<cmath>
     3 #include<vector>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define maxn 300005
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 using namespace std;
     9 
    10 vector<int>ve[maxn];
    11 int book[maxn];
    12 int color[maxn];
    13 int n,m;
    14 int flag,Start;
    15 
    16 int dfs(int pos,int fa,int clr,int num){
    17     if(book[pos]){
    18         if(color[pos]==(clr^1)) flag=1;
    19         if((num-book[pos])&1){
    20             cout<<num-book[pos]<<endl;
    21             Start=pos;
    22             return 0;
    23         }
    24         return 1;
    25     }
    26     book[pos]=num;
    27     color[pos]=clr;
    28     for(int i=0;i<ve[pos].size();i++){
    29         if(ve[pos][i]!=fa){
    30             if(!dfs(ve[pos][i],pos,clr^1,num+1)){
    31                 if(pos!=Start){
    32                     cout<<pos<<" ";
    33                     return 0;
    34                 }
    35                 else{
    36                     cout<<pos<<endl;
    37                     exit(0);
    38                 }
    39             }
    40         }
    41     }
    42     return 1;
    43 }
    44 
    45 int main(){
    46     std::ios::sync_with_stdio(false);
    47     cin>>n>>m;
    48     int a,b;
    49     flag=0;
    50     for(int i=1;i<=m;i++){
    51         cin>>a>>b;
    52         ve[a].push_back(b);
    53         ve[b].push_back(a);
    54     }
    55     mem(book,0);
    56     mem(color,-1);
    57     if(!dfs(1,0,0,1)) return 0;
    58     if(flag){
    59         cout<<-1<<endl;
    60     }
    61     else if(!flag){
    62         cout<<0<<endl;
    63         for(int i=1;i<=n;i++){
    64             if(i!=1){
    65                 cout<<" ";
    66             }
    67             cout<<color[i];
    68         }
    69         cout<<endl;
    70     }
    71 }
    View Code
  • 相关阅读:
    Android_方向传感器
    Android 网络图片查看器与网页源码查看器
    SQLite数据库_实现简单的增删改查
    Android 解析JSON
    多线程
    并发编程
    幂等性
    Django缓存机制
    计算机基础
    RESTful规范
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/9760095.html
Copyright © 2011-2022 走看看