首页 > 其他分享 >CF1991E Coloring Game 题解

CF1991E Coloring Game 题解

时间:2024-09-07 14:25:43浏览次数:3  
标签:std CF1991E 颜色 int 题解 Alice Game Bob col

Description

有一个由 \(n\) 个顶点和 \(m\) 条边组成的无向图。每个顶点可以用三种颜色之一着色: \(1\) 、 \(2\) 或 \(3\) 。初始时,所有顶点都未着色。

Alice 和 Bob 正在玩一个包含 \(n\) 轮的游戏。在每一轮中,都会发生以下两个步骤:

  1. Alice 选择两种不同的颜色。
  2. Bob 选择一个未着色的结点,并用 Alice 选择的两种颜色之一为其着色。

如果存在连接两个相同颜色结点的边,则 Alice 获胜。否则 Bob 获胜。

给你这个图。您的任务是决定您想扮演哪位玩家并赢得游戏。

Solution

首先观察样例会发现有奇环时是 Alice 胜,只有一个偶环就是 Bob 胜。

于是可以猜测图不为二分图时 Alice 胜,否则 Bob 胜。

操作就考虑不为二分图时,Alice 只要一直询问 \((1,2)\),Bob 无论怎么放颜色也无法做到让奇环上相邻的点颜色不一样。

图为二分图时,先假设左部点颜色为 \(1\),右部点颜色为 \(2\)。Alice 每次询问 \((x,y)\) 时,如果 \(x\) 和 \(y\) 中有至少一个满足小于等于 \(2\) 且其在原图中对应的左部/右部点没染完,就染那个满足条件的颜色。

否则一定满足左部/右部点中有至少一边被染完了,且询问的为被染完的颜色和 \(3\)。这样只需要让被染完的那边染 \(3\) 即可。

时间复杂度:\(O(n+m)\)。

Code

#include <bits/stdc++.h>

// #define int int64_t

const int kMaxN = 1e4 + 5;

int n, m;
int col[kMaxN];
bool fl = 1;
std::vector<int> G[kMaxN], id[2];

void dfs(int u) {
  id[col[u] - 1].emplace_back(u);
  for (auto v : G[u]) {
    if (!col[v]) {
      col[v] = 3 - col[u];
      dfs(v);
    } else if (col[v] == col[u]) {
      fl = 0;
    }
  }
}

bool check() {
  fl = 1, id[0].clear(), id[1].clear();
  for (int i = 1; i <= n; ++i) {
    if (!col[i]) {
      col[i] = 1, dfs(i);
    }
  }
  return fl;
}

void dickdreamer() {
  for (int i = 1; i <= n; ++i) G[i].clear(), col[i] = 0;
  std::cin >> n >> m;
  for (int i = 1; i <= m; ++i) {
    int u, v;
    std::cin >> u >> v;
    G[u].emplace_back(v), G[v].emplace_back(u);
  }
  if (!check()) {
    std::cout << "Alice" << std::endl;
    for (int i = 1; i <= n; ++i) {
      std::cout << "1 2" << std::endl;
      int x, y;
      std::cin >> x >> y;
    }
  } else {
    std::cout << "Bob" << std::endl;
    for (int i = 1; i <= n; ++i) {
      int x, y;
      std::cin >> x >> y;
      if (x > y) std::swap(x, y);
      if (x <= 2 && id[x - 1].size()) {
        std::cout << id[x - 1].back() << ' ' << x << std::endl;
        id[x - 1].pop_back();
      } else if (y <= 2 && id[y - 1].size()) {
        std::cout << id[y - 1].back() << ' ' << y << std::endl;
        id[y - 1].pop_back();
      } else {
        std::cout << id[2 - x].back() << ' ' << y << std::endl;
        id[2 - x].pop_back();
      }
    }
  }
}

int32_t main() {
  int T = 1;
  std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

标签:std,CF1991E,颜色,int,题解,Alice,Game,Bob,col
From: https://www.cnblogs.com/Scarab/p/18401650

相关文章

  • CF2009G. Yunli's Subarray Queries 题解
    G1题目要求,对于一个子区间$a_{l\siml+k-1}$,最少要进行多少次单点修改,才能使$\forall\l<i\leql+k-1,a_i=a_{i-1}+1$,其中$k$是固定的。对于这种问题,我们通常有一个trick:将$a_i$变为$a_i-i$。这样的话,我们要求的答案就变为了$k$减去变化后的$a_{l\siml+k-1}$......
  • RecyclerView 高效使用与常见问题解决
    RecyclerView是Android应用开发中最常用的UI组件之一,通常用于显示大量数据列表。尽管功能强大,但如果使用不当,会导致性能问题、数据错乱或滚动卡顿等问题。在本篇文章中,我们将探讨RecyclerView的一些常见坑点,提供解决方案,并附带代码示例。1.坑点:ViewHolder重用导致数据错乱......
  • ctfshow web红包题第二弹题解
    从今天开始记录刷题日常打开靶场平平无奇,看源代码发现如下提示get方式提交cmd参数,猜测是命令执行漏洞,先写个phpinfo();试试。有用,但报错cerror查看显示出来部分php代码,过滤了很多东西if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)) 第一个正则表达式把字母数字几乎全......
  • [ABC137F] Polynomial Construction 题解
    明明有最厉害最好想的插值做法,怎么没有人写呢。思路考虑\(n\)个点可以确定一个\(n-1\)次多项式。如何确定。令\(l_i(x)=\prod_{j\not=i}\frac{(x-x_j)}{(x_i-x_j)}\)。可以发现这个多项式在\(x=x_i\)时值为一,在\(x=x_j(j\not=i)\)时值为零。那么就有:\[F(x)=\su......
  • 洛谷 P3034 Cow Photography G/S——题解
    洛谷P3034题解传送锚点摸鱼环节[USACO11DEC]CowPhotographyG/S题面翻译题目描述今天的奶牛们特别调皮!FarmerJohn想做的只是给排成一排的奶牛拍照,但是在他拍下照片之前,奶牛们一直在移动。具体地说,FJ有\(N\)头奶牛(\(1\leqN\leq20\,000\)),每头奶牛都有一个唯一确......
  • 题解:AT_abc369_e [ABC369E] Sightseeing Tour 详细版
    题目大意给定一个NNN个点,MMM条边的无向图。其中边有边权。有......
  • MySQL 日期函数语法介绍和案例示范以及常见问题解决
    本文将以电商交易系统为例,详细讲解MySQL日期类型及其转化,常用的日期函数,以及一些解决常见问题的方案。一、MySQL日期数据类型MySQL提供了多种日期数据类型,适用于不同的使用场景。常见的日期类型包括DATE、DATETIME、TIMESTAMP、TIME和YEAR。DATE:只存储日期,不包含......
  • 题解:SP3693 KGSS - Maximum Sum
    原题传送门思路分析线段树。这道题让我们进行两种操作,分别是单点修改和区间查询,结合数据范围,很明显是一道线段树。区间里最大的\(A_i+A_j\),其实就是求区间里的最大值和次大值,我们用线段树维护最大值和次大值。建树voidbuild(intnow,inttl,inttr){ if(tl==tr){ tmax......
  • P6638 「JYLOI Round 1」常规 题解
    题目传送门前置知识可持久化线段树|前缀和&差分解法进行差分,区间查询转化成前缀和相减。先将\(\{a\}\)升序排序。设当前询问的区间为\([1,r]\),在\(\{a\}\)中找到一个最大的\(pos\)使得\(a_{pos}\ler\),则\([1,r]\)中所做常规的次数为\(\sum\limits_{i=1......
  • 使用flask进行Mock Server模拟接口操作及问题解决
    1.flask介绍flask是一个轻量级的pythonweb微框架2.MockServer介绍MockServer是一个开源的模拟服务器,它可以定义和记录API交互,支持各种http方法(get、post、put、delete),可以自定义响应内容,例如返回静态文件可以使用flask来搭建一个mock模拟服务3.模拟接口先安装flaskpip......