luogu 4429 染色

蹲街弑〆低调 提交于 2021-02-13 17:48:05

bjoi 2018 染色 推了个错误结论得了60分?

题目大意:

一个无重边和自环的无向图,并且对每个点分别给了一个大小为2的颜色集合,只能从这个集合中选一种颜色给这个点染色

求一个染色方案使得没有两个有边相连的点被染了相同的颜色

求是否无论颜色集合是什么,均有办法按照要求染色

思路:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long 
10 #define MAXN 10100
11 #define inf 2139062143
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 struct edge{int s,t,nxt;}e[MAXN<<2];
21 int n,m,fst[MAXN],cnt,ans;
22 int d[MAXN],vis[MAXN],fa[MAXN];
23 void add(int u,int v)
24 {
25     e[++cnt].s=u,e[cnt].t=v,e[cnt].nxt=fst[u];
26     fst[u]=cnt,d[u]++;
27 }
28 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
29 queue <int> q;
30 vector <int> v[MAXN];
31 int main()
32 {
33     int T=read();
34     while(T--)
35     {
36         n=read(),m=read();int a,b;
37         for(int i=1;i<=MAXN;i++) v[i].clear();
38         for(int i=1;i<=n;i++) fa[i]=i;
39         memset(fst,0,sizeof(fst));
40         memset(d,0,sizeof(d));cnt=0,ans=1;
41         memset(vis,0,sizeof(vis));
42         for(int i=1;i<=m;i++) {a=read(),b=read();add(a,b);add(b,a);}
43         for(int i=1;i<=n;i++)
44             if(d[i]==1) {q.push(i);vis[i]=1;}
45         while(!q.empty())
46         {
47             a=q.front();q.pop();b=-1;
48             for(int j=fst[a];j;j=e[j].nxt)
49                 if(!vis[e[j].t]) b=e[j].t;
50             if(b==-1) continue;
51             d[b]--;
52             if(d[b]==1){vis[b]=1;q.push(b);}
53         }
54         for(int i=1;i<=2*m;i+=2)
55             if(!vis[e[i].s]&&!vis[e[i].t])
56             {
57                 int a=find(e[i].s),b=find(e[i].t);
58                 if(a!=b) fa[a]=b;
59             }
60         for(int i=1;i<=n;i++) v[find(i)].push_back(i);
61         for(int i=1;i<=n;i++)
62             if(fa[i]==i)
63             {
64                 if(v[i].size()==1) continue;
65                 int x=0,y=-1,z=-1,can=1;
66                 for(int j=0;j<v[i].size();j++)
67                 {
68                     if(d[v[i][j]]>3) can=0;
69                     if(d[v[i][j]]==3)
70                     {
71                         x++;
72                         if(x==1) y=v[i][j];
73                         else z=v[i][j];
74                     }
75                 }
76                 if(!can) ans=0;
77                 if(x==1||x>2) ans=0;
78                 if((!x)&&v[i].size()%2==1) ans=0;
79                 if(x==2)
80                 {
81                     if(v[i].size()%2==0) ans=0;
82                     int p=0;
83                     for(int j=0;j<v[i].size();j++)
84                         if(v[i][j]!=y&&v[i][j]!=z)
85                         {
86                             a=0;
87                             for(int k=fst[v[i][j]];k;k=e[k].nxt)
88                                 if(e[k].t==y||e[k].t==z) a++;
89                             if(a==2) p++;
90                         }
91                     if(p<2) ans=0;
92                 }
93             }
94         if(ans) puts("YES");
95         else puts("NO");
96     }
97 }
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!