zoukankan      html  css  js  c++  java
  • 【xsy3355】图 思维

    题目大意:给你一个n个点m条无向边的图,问这个图是否能够:

    1,被四染色(用四种颜色给图染色,且相邻点颜色不同)。

    2,找出一个奇环,满足在原图中去掉这个奇环后每个点依然相邻。

    请输出1或者2中的任意一种,如果不能就输出类似-1的东西。

    数据范围:n,m≤300000

    xfzIQ=-1

    我们首先构造一棵生成树出来,这个生成树显然是一个二分图,二分图显然可以黑白染色。

    对于原图中的非树边,我们把这些变构成一个图G,若G为二分图,显然原图就可以四染色了。

    若G不是二分图,那么G中必有奇环,我们把奇环找出来输出就可以了。

    智商被侮辱系列题目。

     1 #include<bits/stdc++.h>
     2 #define M 300005
     3 using namespace std;
     4 
     5 int f[M]={0}; int get(int x){return f[x]==x?x:f[x]=get(f[x]);}
     6 struct edge{int u,next;}e[M*2]={0}; int head[M]={0},use=0;
     7 void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;}
     8 
     9 int col1[M]={0},col2[M]={0};
    10 int n,m,noX=0,noY=0;
    11 int u[M]={0},v[M]={0},sel[M]={0};
    12 
    13 void dfs(int x,int col){
    14     col1[x]=col; if(col==1) col=2; else col=1;
    15     for(int i=head[x];i;i=e[i].next)
    16     if(col1[e[i].u]==0) dfs(e[i].u,col);
    17 }
    18 void dfs2(int x,int col){
    19     col2[x]=col; if(col==1) col=2; else col=1;
    20     for(int i=head[x];i;i=e[i].next)
    21     if(col2[e[i].u]==0) dfs2(e[i].u,col);
    22     else{
    23         if(col2[e[i].u]==col2[x]){
    24             noX=e[i].u;
    25             noY=x;
    26             //return;
    27         }
    28     }
    29 }
    30 
    31 int ans[M]={0},cnt=0;
    32 int getans(int x,int fa){
    33     if(x==noY){
    34         ans[++cnt]=x;
    35         return 1;
    36     }
    37     for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa){
    38         if(getans(e[i].u,x)){
    39             ans[++cnt]=x;
    40             return 1;
    41         }
    42     }
    43     return 0;
    44 }
    45 
    46 int main(){
    47     scanf("%d%d",&n,&m);
    48     for(int i=1;i<=n;i++) f[i]=i;
    49     for(int i=1;i<=m;i++){
    50         scanf("%d%d",u+i,v+i);
    51         int U=get(u[i]),V=get(v[i]);
    52         if(U==V) continue;
    53         sel[i]=1; f[U]=V;
    54         add(u[i],v[i]); add(v[i],u[i]);
    55     }
    56     dfs(1,1);
    57     memset(head,0,sizeof(head)); use=0;
    58     for(int i=1;i<=m;i++) if(sel[i]==0){
    59         add(u[i],v[i]); add(v[i],u[i]);
    60     }
    61     for(int i=1;i<=n;i++)
    62     if(col2[i]==0) dfs2(i,1);
    63     
    64     if(noX==0){
    65         printf("A ");
    66         for(int i=1;i<=n;i++)
    67         printf("%d ",col1[i]+(col2[i]-1)*2);
    68         return 0;
    69     }
    70     
    71     memset(head,0,sizeof(head)); use=0;
    72     for(int i=1;i<=n;i++) f[i]=i;
    73     for(int i=1;i<=m;i++) if(sel[i]==0){
    74         if(col2[u[i]]==col2[v[i]]) continue;
    75         int U=get(u[i]),V=get(v[i]);
    76         if(U==V) continue;
    77         f[U]=V;
    78         add(u[i],v[i]); add(v[i],u[i]);
    79         if(get(noX)==get(noY)) break;
    80     }
    81     getans(noX,0);
    82     printf("B %d ",cnt);
    83     for(int i=1;i<=cnt;i++) printf("%d ",ans[i]);
    84 }
  • 相关阅读:
    LIS(最长的序列)和LCS(最长公共子)总结
    SVN最有效的方法打基线
    SRM 638 Div2
    poj 2038 Team Rankings 枚举排列
    BZOJ 2809 APIO2012 dispatching Treap+启示式合并 / 可并堆
    Java中的工具类和新特性
    微信公众平台PHP开发
    全国各大 oj 分类题集...
    语言处理程序
    Android开发
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10503467.html
Copyright © 2011-2022 走看看