题目传送门

https://codeforces.com/contest/1103/problem/C

题解

这个题还算一个有难度的不错的题目吧。

题目给出了两种回答方式:

  1. 找出一条长度 \(\geq \frac nk\) 的路径;
  2. 找出 \(k\) 个简单环,满足长度不是 \(3\) 的倍数,并且每个环至少存在一个点不在别的环中。

很显然题目并不是要你随便挑一种回答方式开始单独研究。最有可能的情况是两种回答方式可以替补。


如果我们随便作出原图的一棵生成树,如果最长的路径长度 \(\geq \frac nk\),那么我们可以直接输出。否则,很容易发现,这棵树上至少有 \(k\) 个叶子。

很容易把 \(k\) 个叶子往第二种回答方式中的 \(k\) 个环上联想。但是第二个回答方式中的几个条件我们还都要满足。

对于“每个环至少存在一个点不在别的环中”这个条件,等价于就是说,每一个叶子不会和其余的叶子有连边。dfs 树可以保证这个性质,同时 dfs 树还可以保证,每一个点出来的非树边一定是返祖边。那么,建立 dfs 树以后,每个环就是每一个叶子和它的一些祖先之间的事情了。

接着考虑环的长度不是 \(3\) 的倍数的这个条件。

首先,我们不妨假设叶子 \(x\) 连向的两条返祖边指向的点分别为 \(x\) 的祖先为 \(f_1\) 和 \(f_2\)。

那么我们得到了三个环 \(x \to f_1 \to x\),\(x\to f_2 \to x\),\(f_1\to f_2 \to x\)。

然后三条路径的长度为别为 \(dep_x - dep_{f_1} + 1\),\(dep_x - dep_{f_2} + 1\),\(dep_{f_1} - dep_{f_2} + 2\)。

如果 \(dep_x - dep_{f_1} + 1\) 和 \(dep_x - dep_{f_2} + 1\) 都是 \(3\) 的倍数(否则输出其中的一个就可以了),那么就是说 \((dep_x - dep_{f_1}) - (dep_x - dep_{f_2}) + 2 = dep_{f_1} - dep_{f_2} + 2\) 模上 \(3\) 应该是 \(2\)。

也就是说,上面的三个环中至少存在一个环的长度不是 \(3\) 的倍数。输出哪一个即可。


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

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 2.5e5 + 7;
const int M = 5e5 + 7; int n, m, k, nk;
int fz[N][3], f[N], chk[N], vis[N], dep[N]; struct Edge { int to, ne; } g[M << 1]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); } inline void dfs(int x, int fa = 0) {
f[x] = fa, vis[x] = 1, dep[x] = dep[fa] + 1;
int &c = chk[x] = 1;
for fec(i, x, y)
if (!vis[y]) c = 0, dfs(y, x);
else if (y != fa && fz[x][0] < 2) fz[x][++fz[x][0]] = y;
} inline void work() {
dfs(1);
for (int i = 1; i <= n; ++i) if (dep[i] >= nk) {
puts("PATH");
printf("%d\n", dep[i]);
for (int x = i; x; x = f[x]) printf("%d%c", x, " \n"[!f[x]]);
return;
}
puts("CYCLES");
int cnt = 0;
for (int i = 1; i <= n; ++i) if (chk[i]) {
++cnt;
if (dep[fz[i][1]] < dep[fz[i][2]]) std::swap(fz[i][1], fz[i][2]);
if ((dep[i] - dep[fz[i][1]]) % 3 != 2) {
int ans = 0;
for (int x = i; x != f[fz[i][1]]; x = f[x]) ++ans;
printf("%d\n", ans);
for (int x = i; x != f[fz[i][1]]; x = f[x]) printf("%d%c", x, " \n"[x == fz[i][1]]);
} else {
if ((dep[i] - dep[fz[i][2]]) % 3 != 2) {
int ans = 0;
for (int x = i; x != f[fz[i][2]]; x = f[x]) ++ans;
printf("%d\n", ans);
for (int x = i; x != f[fz[i][2]]; x = f[x]) printf("%d%c", x, " \n"[x == fz[i][2]]);
} else {
int ans = 1;
for (int x = fz[i][1]; x != f[fz[i][2]]; x = f[x]) ++ans;
printf("%d\n", ans);
for (int x = fz[i][1]; x != f[fz[i][2]]; x = f[x]) printf("%d ", x);
printf("%d\n", i);
}
}
if (cnt >= k) return;
}
assert(cnt >= k);
} inline void init() {
read(n), read(m), read(k), nk = (n - 1) / k + 1;
int x, y;
for (int i = 1; i <= m; ++i) read(x), read(y), adde(x, y);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

CF1103C Johnny Solving (Codeforces Round #534 (Div. 1)) 思维+构造的更多相关文章

  1. Codeforces Round #534 (Div. 2)

    B. Game with string 题意: 给出一个字符串s只包括小写字母.当轮到一个玩家的时候,他可以选择两个连续且相等的字母并且删除它.当一个玩家没得删的时候他就输了. 题解: 乍一看有点懵, ...

  2. Codeforces Round #534 (Div. 2) Solution

    A. Splitting into digits Solved. #include <bits/stdc++.h> using namespace std; int n; void sol ...

  3. 20191028 Codeforces Round #534 (Div. 1) - Virtual Participation

    菜是原罪. 英语不好更是原罪. \(\mathrm{A - Grid game}\) 题解 \(4 \times 4\) 的格子,两种放法. 发现这两种在一起时候很讨厌,于是强行拆分这个格子 上面 \ ...

  4. Codeforces Round #534 (Div. 2) D. Game with modulo(取余性质+二分)

    D. Game with modulo 题目链接:https://codeforces.com/contest/1104/problem/D 题意: 这题是一个交互题,首先一开始会有一个数a,你最终的 ...

  5. CF1103D Codeforces Round #534 (Div. 1) Professional layer 状压 DP

    题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ...

  6. Codeforces Round #534 (Div. 1)

    A 构造题 有一个44的方格 每次放入一个横向12或竖向2*1的方格 满了一行或一列就会消掉 求方案 不放最后一行 这样竖行就不会消 然后竖着的放前两行 横着的放第三行 循环放就可以啦 #includ ...

  7. Codeforces Round #534 (Div. 2)D. Game with modulo-1104-D(交互+二分+构造)

    D. Game with modulo time limit per test 1 second memory limit per test 256 megabytes input standard ...

  8. [ACM]Codeforces Round #534 (Div. 2)

    A. Splitting into digits Vasya has his favourite number n. He wants to split it to some non-zero dig ...

  9. Codeforces 1104 D. Game with modulo-交互题-二分-woshizhizhang(Codeforces Round #534 (Div. 2))

    D. Game with modulo time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. sed扩展命令使用

    [root@b ~]# cat f.txt inet addr:192.168.0.110 Bcast:192.168.0.255 Mask:255.255.255.0[root@b ~]# cat ...

  2. IDEA 中常用快捷键的使用

    IDEA 中快捷键的使用 1:知道类名全局查找类:   Ctrl+Shift+Alt+N;      全局搜索: Ctrl+Shift+R 2:快速定位到类的文件夹: 3:  优化导入的类和包 (删除 ...

  3. ICML 2019 分析

    ICML 2019 分析 Word Embeddings Understanding the Origins of Bias in Word Embeddings Popular word embed ...

  4. C# .Net动态调用webService实现思路及代码

    加载: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syste ...

  5. 003-unity3d 物理引擎-示例2 打箱子

    一.基础知识点 1.坐标.向量等 )) { //1.将鼠标坐标 转化为 世界坐标 由于鼠标z轴 可能不存在,故自定义为3 Vector3 targetPos = Camera.main.ScreenT ...

  6. C# user32.dll找窗口时,使用GetClass方法解决 【带有系统自动编译的窗体类后缀名】 问题

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern int G ...

  7. 常用获取Android崩溃日志和IOS崩溃日志的几种方法

    一:前言 在日常测试app时,经常会遇到崩溃问题,测试快速抓取到崩溃日志可以有效方便开发进行定位,快速解决问题所在测试做到测试分析,定位是非常重要的,这也是判断一个测试能力指标的一大维度. 二:And ...

  8. <class 'blog.admin.CategoryAdmin'>: (admin.E108) The value of 'list_display[0]' refers to 'mame', which is not a callable, an attribute of 'CategoryAdmin', or an attribute or method on 'blog.Category'

    系统反馈此类错误是因为行列映射时无法对应: 引起无法对应的原因有: 定义是缺少某列,定义时缩进导致,映射关系时缺少某列,(通俗讲列名对应不上). 这种错误多是python中的 因为其中对于空格的要求是 ...

  9. 【Linux开发】【Qt开发】arm-linux-gnueabihf-gdb versus gdb-multiarch

    主要是说,在Ubuntu14.04 64bit的操作系统上,配置Qt的gdb和gcc的时候,在Qt build&run选项中,debugger中选中arm-linux-gnuabihf-gdb ...

  10. 【QT开发】QT在windows下的exe应用程序如何在别人的电脑上直接运行

     当你利用QT编译了一个可执行程序,需要将这个可执行程序拷贝到别人的电脑上运行,这个时候除了这个可执行程序外,还需要支持的库才可用运行.一般来说通过下面的方法可以实现.     首先,需要看你用的是什 ...