zoukankan      html  css  js  c++  java
  • 【Foreign】红与蓝 [暴力]

    红与蓝

    Time Limit: 10 Sec  Memory Limit: 256 MB

    Description

      

    Input

      

    Output

      

    Sample Input

      2
      2
      0 1
      -1 -1
      2
      0 1
      -1 1

    Sample Output

      1 2
      -1

    HINT

      

    Main idea

      每个节点有红色、蓝色或者无色,给定了若干叶子节点的颜色,非叶子节点的颜色定义为所有儿子中颜色出现次数最多的一个,若一样则无色。叶子节点无色则可以染色,红色先手,蓝色接着轮流染色,最后若根为红色则胜利否则失败。胜利的话还要求输出可行方案。

    Source

      我们可以先O(n)求出在不动叶子节点情况下每一个点的颜色,由于每个一个点只有奇数个儿子,且红色先手。那么这时候如果根节点为红色或者无色则必胜,蓝色则必败

      然后我们分情况讨论,蓝色就直接输出“-1”,结束即可。如果根是红色的话,显然染色对于答案是没有什么影响的,所以所有无色的叶子节点都可以是解

      现在我们来讨论根无色的情况:我们计算每一个点中儿子的蓝色个数和红色个数,如果一个点是 (蓝色,且蓝色个数=红色个数+1) 或者 (无色,蓝色个数=红色个数)则可以往下递归,找到叶子节点为无色则可以是解。我们来解释一下:

      1. 蓝色,蓝色个数=红色个数+1:如果往下走有可染色的叶子节点,那么必然逼着蓝色接着染,否则蓝色就输了。这个点的颜色就会是:无、蓝、无……由于红色先手,所以最后这个点是可以变成无色的,因为递归做到这里,所以这个点的父亲节点是白色的,然后这个点变为了白色,它的父亲就少了一个蓝色儿子,就变成红色了。

      2. 无色,蓝色个数=红色个数:如果往下走有可染色的叶子节点,那么这一条无色链上都会变成红色的,显然可行。

      这样我们暴力递归往下讨论,就解决了这个问题。

    Code

      1 #include<iostream>  
      2 #include<algorithm>  
      3 #include<cstdio>  
      4 #include<cstring>  
      5 #include<cstdlib>  
      6 #include<cmath>  
      7 using namespace std;
      8 
      9 const int ONE = 100005;
     10 
     11 int T;
     12 int n,x,root;
     13 int Val[ONE];
     14 int next[ONE],first[ONE],go[ONE],tot;
     15 int ans_num,Ans[ONE];
     16 
     17 void Add(int u,int v)
     18 {
     19         next[++tot]=first[u];    first[u]=tot;    go[tot]=v;
     20 }
     21 
     22 int get()
     23 { 
     24         int res,Q=1;    char c;
     25         while( (c=getchar())<48 || c>57)
     26         if(c=='-')Q=-1;
     27         if(Q) res=c-48; 
     28         while((c=getchar())>=48 && c<=57) 
     29         res=res*10+c-48; 
     30         return res*Q; 
     31 }
     32 
     33 void Deal_first(int u)
     34 {
     35         for(int e=first[u];e;e=next[e])
     36         {
     37             int v=go[e];
     38             Deal_first(v);
     39             Val[u] += Val[v];
     40         }
     41         if(Val[u] < 0) Val[u] = -1;
     42         else if(Val[u] > 0) Val[u] = 1;
     43 }
     44 
     45 void Dfs(int u)
     46 {
     47         if(!Val[u] && !first[u])
     48         Ans[++ans_num] = u;
     49         
     50         for(int e=first[u];e;e=next[e])
     51         {
     52             int v=go[e];
     53             int tot=0;
     54             for(int i=first[v];i;i=next[i])
     55                 tot+=Val[go[i]];
     56             if(tot==0 || tot==-1) Dfs(v);
     57         }
     58 }
     59 
     60 void Solve()
     61 {
     62         n=get();
     63         tot=0; memset(first,0,sizeof(first));
     64         for(int i=1;i<=n;i++)
     65         {
     66             x=get();
     67             if(!x) root=i;
     68             else Add(x,i);
     69         }
     70         
     71         for(int i=1;i<=n;i++)
     72         {
     73             Val[i]=get();
     74             if(Val[i]==0) Val[i]=1;
     75             else if(Val[i]==1) Val[i]=-1;
     76             else Val[i]=0;
     77         }
     78         
     79         Deal_first(root);
     80         if(Val[root] < 0)
     81         {
     82             printf("-1");
     83             return;
     84         }
     85         else
     86         {
     87             ans_num=0;
     88             if(Val[root]==0) Dfs(root),sort(Ans+1,Ans+ans_num+1);
     89             if(Val[root]==1) for(int i=1;i<=n;i++) if(!Val[i] && !first[i]) Ans[++ans_num]=i;
     90             
     91             printf("%d ",ans_num);
     92             for(int i=1;i<=ans_num;i++)
     93                 printf("%d ",Ans[i]);
     94         }
     95 }
     96 
     97 int main()
     98 {      
     99         T=get();
    100         while(T--)
    101             Solve(),printf("
    ");
    102 }
    View Code

     

      

     

  • 相关阅读:
    css实现图像边框的样式
    css3 实现div靠右对齐
    将div水平,垂直居中的方式
    使用vue-cli可视化的方式创建项目后如何关闭ESLint代码检测
    清楚html和css标签自带默认样式
    vue动态请求到的多重数组循环遍历,取值问题,如果某个值存在则显示,不存在则不显示。
    python 编程
    python 错题集
    python+selenium页面自动化 元素定位实际遇到的各种问题(持续更新)
    使用Fiddle抓取IOS手机
  • 原文地址:https://www.cnblogs.com/BearChild/p/6506708.html
Copyright © 2011-2022 走看看