luogu 4429 染色
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 }