师大校赛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\n");
         else{
             if( (ans&1) ==0)printf("Maze\n");
             else printf("Fat Brother\n");
         }
    }

    return 0;
}

时间: 2024-12-12 12:20:30

师大校赛D coloring Game 并查集的相关文章

测试赛F - Dragon Balls(并查集)

F - Dragon Balls Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Five hundred years later, the number of dragon balls will increase unexpectedly, so it's too difficult for Monkey King(WuKong) to

zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)

题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值. 用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路,这条路连接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值大.如果让集合B加入集合A,就是让中心城市位于集合A,那么可以确定这两个集合合并之后的总权值为: A的权值总和+B的数量*当前这条路的权值.同样算出让集合B加入集合A的情况,取两者合并后

杭师大校赛总结

感想: 这次校赛总有些遗憾,有两道题目我总觉得可以做出来,但是却又没做出来, 一个是没有将以前做过的题目的规律总结,就是没有好好的整理以前的知识点, 还有就是做题的速度太慢了,H题到了最后才想出一个新的点子,还没来得及实现比赛就结束了. 总的来说,我觉得比赛就是考察5个方面,速度,细节,模板(可能不太常用),语言(包括C++)和配合, 只要抓住这几个方面就好了,就我而言,还要提高速度,注重细节,不断总结,完善自己的模板. 相信下一次我一定能够A更多的题. 原文地址:https://www.cnb

蓝桥杯模拟赛-引爆炸弹-DFS+并查集

今天整理电脑,翻出来了很久以前大佬给的题,贴一下. 引爆炸弹 1000ms 在一个 n×m的方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去. 现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆. 输入格式 第一行输两个整数 n,mn,mn,m,用空格隔开. 接下来 nnn 行,每行输入一个长度为 mmm 的字符串,表示地

2014东北农大校赛--D.Cross the middle (任意两点最短路径 Floyd)

Cross the middle Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 36  Solved: 13 [Submit][Status][Web Board] Description n个点的图,给出任意两点之间的距离,m个询问,每次询问Mid是否可能出现在从Start到End的最短路径上. Input 第一行n,m 接下来是一个n*n的邻接矩阵,w[i][j]表示i到j的距离 接下来m行 每行start,end,mid N,m<=100,

2014东北农大校赛--A. Paint it! (预处理)

1141: A.Paint it! Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 13  Solved: 10 [Submit][Status][Web Board] Description 有一个n*m的棋盘,每个格子只可能是黑和白两种颜色,你可以使用染料将某个格子染成黑色或者白色.求最少需要染多少个格子, 能使当前的棋盘变成类似于国际象棋的棋盘(每个格子临边的四个格子颜色都不与该格子的颜色相同). Input n m(n,m<=100) 接下

2017端午欢乐赛——Day1T3(树的直径+并查集)

//前些天的和jdfz的神犇们联考的模拟赛.那天上午大概是没睡醒吧,考场上忘了写输出-1的情况,白丢了25分真是**. 题目描述     小C所在的城市有 n 个供电站,m条电线.相连的供电站会形成一个供电群,那么为了节省材料,供电群是一棵树的形式,也即城市是一个森林的形式(树:V个点,V-1条边的无向连通图,森林:若干棵树).每个供电群中不需要所有供电站都工作,最少只需要一个工作,其余的就都会通过电线收到电,从而完成自己的供电任务.当然,这样会产生延迟.定义两个供电站的延迟为它们之间的电线数量

acm集训训练赛(二)D题【并查集】

一.题目 Description There is a town with N citizens. It is known that some pairs of people are friends. According to the famous saying that ?The friends of my friends are my friends, too? it follows that if A and B are friends and B and C are friends th

2014工大校赛题目以及解

a,b题不说. c题思路是每次枚举俩个点,用半径R确定最大的圆(这样的圆有俩个,求圆心手算有点小麻烦),更新最大值,3次方的,100个点,不会超时. D题是枚举+贪心,所有物品一共只能是N+1种被拿的情况:要么全是用R(该位子是若用右手标记R,若用左手标记L):RRR...RRR,或者第一个物品用L:LRRR...RR,.....依次到LLLLLL..LLL,一个序列来记录每个物品是被左手还是右手拿.枚举所有序列,如LLL...RRR,贪心:那必然是一次L一次R,多出来的需要额外开销能量.如LL