• 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 }
    View Code
  • 相关阅读:
    如何理解联合文件系统?
    Docker 学习笔记(一)
    Bzoj 3124: [Sdoi2013]直径 题解
    Bzoj 3131 [Sdoi2013]淘金 题解
    欧拉路(题目)
    硬币问题
    线段树、树状数组
    Splay树、Treap树
    模拟退火
    广搜题目(一本通)
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/8885993.html
Copyright © 2020-2023  润新知