码迷,mamicode.com
首页 > 其他好文 > 详细

【xsy3355】图 思维

时间:2019-03-09 23:26:15      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:sizeof   范围   using   void   四种   c++   clu   efi   add   

题目大意:给你一个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 }

 

【xsy3355】图 思维

标签:sizeof   范围   using   void   四种   c++   clu   efi   add   

原文地址:https://www.cnblogs.com/xiefengze1/p/10503467.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!