zoukankan      html  css  js  c++  java
  • 师大校赛D coloring Game 并查集

    这题说的是 在一个 森林中 两个人在这棵树上涂颜色,黑色或者白色,第一次只能在1 号节点上涂色 第二次 只能在2上涂,以此类推, 在每个节点上只能涂黑色或者白色,并且相邻的点不能有相同的颜色,最后求不能填的人就输了。

    每个点周围的比他小的点 都会有一个祖先(或者是他们自己),我们知道他周围的点的祖先中最小的那个点 一定是影响他的最小的点 那么他取什么值这就不那么重要了。无论他取黑还是白,后面的就只是相对而言,那么如果他受到第二小或者以上的点的影响,那么他就一定不能了, 还有就是当他和他周围点离他们共同祖先的距离一样的时候也是不行的。

    哪个先出现错误哪个就失败了。

    #include <iostream>
    #include <algorithm>
    #include<string.h>
    #include<vector>
    #include <cstdio>
    using namespace std;
    const int maxn=100005;
    struct Edg{
       int to,nxt;
       Edg(int a=0,int b=0){
           to=a; nxt=b;
       }
    }P[maxn*5];
    int len[maxn],fa[maxn],first[maxn],pos;
    void add(int a, int b){
         P[pos].to=b; P[pos].nxt=first[a];
         first[a]=pos++;
    }
    int find(int x){
       if(x!=fa[x]){
           int f=find(fa[x]);
           len[ x ] = len[ fa[x] ]^len[x];
           fa[ x ] = f;
       }
       return fa[x];
    }
    bool uunion(int x, int y){
           int fx=find(x);
           int fy=find(y);
           if(fx==fy){
             return len[x]!=len[y];
           }
           if(fx<fy){
              fa[fy]=fx;
              len[fy ] = len[x]^len[y]^1;
           }else{
              fa[fx]=fy;
              len[fx] = len[x]^len[y]^1;
           }
           return true;
    }
    int qq[maxn*2];
    int main()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        int N,M,cas;
        scanf("%d",&cas);
        for(int cc=1; cc<=cas; cc++){
                pos=0;
              scanf("%d%d",&N,&M);
              for(int i=0; i<=N; i++){
                 first[i]=0; fa[i]=i; len[i]=0;
              }
             for(int i=0; i<M; i++){
                 int a,b;
                 scanf("%d%d",&a,&b);
                 add(a,b); add(b,a);
             }
             int ans=-1;
             for(int i=1; i<=N&&ans==-1; i++){
                 int pp=0;
                 for(int j=first[i]; j ; j=P[j].nxt){
                       int to=P[j].to;
                       if(to>i)continue;
                       qq[pp++]=find(to);
                 }
                 sort(qq,qq+pp);
                pp = unique(qq,qq+pp)-qq;
                for(int j=1; j<pp; j++)
                     if( qq[j]%2 != i%2 )ans=i;
                for(int j=first[i]; j; j=P[j].nxt){
                     int to=P[j].to;
                     if(to>i) continue;
                     if(!uunion(i,to))ans=i;
                }
             }
             printf("Case %d: ",cc);
             if(ans==-1)printf("Draw
    ");
             else{
                 if( (ans&1) ==0)printf("Maze
    ");
                 else printf("Fat Brother
    ");
             }
        }
    
    
    
    
    
    
        return 0;
    }
    View Code
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/Opaser/p/4444995.html
Copyright © 2011-2022 走看看