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 }
来源:oschina
链接:https://my.oschina.net/u/4403012/blog/4001151