• [bzoj5295]染色


    将这张图化简,不断删掉度为1的点(类似于拓扑排序),构成了一张由环组成的图
    考虑一个连通块中,设点数为n,边数为m(已经删掉了度为1的点),那么一共只有三种情况:
    1.一个环($n=m$),一定为YES
    2.多个环嵌套($n+1<m$),一定为NO
    3.两个环($n+1=m$),其实可以看成有两个点(可以重合),然后这两个点中间有三条路径,记长度分别为l1,l2,l3,那么有结论:当且仅当三条边依次为2,2和偶数时成立
    证明:
    首先三条边必然要同奇偶,否则存在奇环,对于奇环上的点都选择集合${AB}$即可卡掉
    然后如果三条边都是奇数,由于原图不存在重边,因此最多只有一条路径上没有点,不妨设$l1,l2>1$,可以用l3来构造两点不同,l1来构造不能选AB,l2来构造不能选BA
    那么三条边都是偶数,如果其中只有1条边小于等于2,那么$l1,l2ge 4$,同理可以用l3来构造两点相同,l1来卡掉都选A,l2来卡掉都选B
    当有两条路径长度小于等于2(由于没有重边,所以一定都恰好为2),很容易发现无法卡掉
     
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 10005
     4 queue<int>q;
     5 vector<int>v[N];
     6 int t,n,m,x,y,a[N],r[N],vis[N];
     7 void dfs(int k,int fa){
     8     if (vis[k])return;
     9     vis[k]=1;
    10     if (r[k]>2)a[++a[0]]=k;
    11     x++;
    12     for(int i=0;i<v[k].size();i++)
    13         if ((r[v[k][i]]>1)&&(v[k][i]!=fa)){
    14             if ((fa)||(!vis[v[k][i]]))y++;
    15             dfs(v[k][i],k);
    16         }
    17 }
    18 void calc(int k,int fa,int x,int s){
    19     if (k==x){
    20         a[++a[0]]=s;
    21         return;
    22     }
    23     for(int i=0;i<v[k].size();i++)
    24         if ((r[v[k][i]]>1)&&(v[k][i]!=fa))calc(v[k][i],k,x,s+1);
    25 }
    26 int main(){
    27     scanf("%d",&t);
    28     while (t--){
    29         scanf("%d%d",&n,&m);
    30         memset(r,0,sizeof(r));
    31         memset(vis,0,sizeof(vis));
    32         for(int i=1;i<=n;i++)v[i].clear();
    33         for(int i=1;i<=m;i++){
    34             scanf("%d%d",&x,&y);
    35             r[x]++;
    36             r[y]++;
    37             v[x].push_back(y);
    38             v[y].push_back(x);
    39         }
    40         for(int i=1;i<=n;i++){
    41             if (!r[i])vis[i]=1;
    42             if (r[i]==1)q.push(i);
    43         }
    44         while (!q.empty()){
    45             int k=q.front();
    46             q.pop();
    47             vis[k]=1;
    48             for(int i=0;i<v[k].size();i++)
    49                 if (--r[v[k][i]]==1)q.push(v[k][i]);
    50         }
    51         bool flag=0;
    52         for(int i=1;i<=n;i++){
    53             x=y=a[0]=0;
    54             dfs(i,0);
    55             if ((x==y)&&(x%2==0))continue;
    56             if ((a[0]<2)||(x+1<y)||(x==y)&&(x&1)){
    57                 flag=1;
    58                 break;
    59             }
    60             x=a[1];
    61             y=a[2];
    62             a[0]=0;
    63             calc(x,0,y,0);
    64             sort(a+1,a+a[0]+1);
    65             if ((a[1]&1)||(a[2]&1)||(a[3]&1)||(a[2]>2)){
    66                 flag=1;
    67                 break;
    68             }
    69         }
    70         if (flag)printf("NO
    ");
    71         else printf("YES
    ");
    72     }
    73 }
    View Code
  • 相关阅读:
    IDEA的Debug详解
    websocket学习(转载)
    Shiro授权及注解式开发
    Redis分布式缓存安装和使用
    JEESZ-SSO解决方案
    英语是学习Java编程的基础吗
    深入分析 ThreadLocal 内存泄漏问题
    这些JVM命令配置参数你知道吗?
    安全开发Java动态代理
    学java编程软件开发,非计算机专业是否能学
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/12054675.html
Copyright © 2020-2023  润新知