【题目链接】

  • 点击打开链接

【思路要点】

  • 不难发现各个边双连通分量可以分开处理,桥边可以直接删除。
  • 可以证明,对于每一个边双连通分量,当 M−NM-NM−N 超过 O(N)O(\sqrt{N})O(N​) 级别,答案一定为 YesYesYes 。
  • 那么,将剩余图中的度为 222 的点缩去,剩余的图是一张点数和边数均在 O(N)O(\sqrt{N})O(N​) 级别的图。
  • 选择一个起始点,找到包含其的所有环,再删去该起始点,每个环会被搜到恰好 222 次。
  • 每走出一步均判断当前点与起始点的连通性以确保能够搜到一个环。
  • 至多会搜到 O(N)O(N)O(N) 个环,每个环环长为 O(N)O(\sqrt{N})O(N​) 个点,判断连通性需要 O(N)O(\sqrt{N})O(N​) 的时间。
  • 总时间复杂度 O(N2)O(N^2)O(N2) 。
  • 互测当时笔者采用没有判断连通性的做法配合贪心和卡时输出 NoNoNo 通过了本题。

【代码】

// Standard Solution O(N ^ 2)
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1e6 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
template <typename T> void write(T x) {if (x < 0) x = -x, putchar('-');if (x > 9) write(x / 10);putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {write(x);puts("");
}
int x[MAXM], y[MAXM], f[MAXN];
int n, m, em, v, e, ans[MAXN];
vector <int> a[MAXN], p; set <int> b[MAXN];
vector <pair <pair <int, int>, int>> c[MAXN];
bool vis[MAXN], vise[MAXN], iskey[MAXN];bool instack[MAXN];
int tot, belong[MAXN], top, Stack[MAXN];
int timer, dfn[MAXN], low[MAXN];
void tarjan(int pos, int fa) {low[pos] = dfn[pos] = ++timer;v++, e += a[pos].size();Stack[++top] = pos;instack[pos] = true;for (unsigned i = 0; i < a[pos].size(); i++) {if (a[pos][i] == fa) continue;if (dfn[a[pos][i]] == 0) {tarjan(a[pos][i], pos);low[pos] = min(low[pos], low[a[pos][i]]);} else if (instack[a[pos][i]]) low[pos] = min(low[pos], dfn[a[pos][i]]);}if (low[pos] == dfn[pos]) {int tmp = Stack[top--];belong[tmp] = ++tot;instack[tmp] = false;while (tmp != pos) {tmp = Stack[top--];belong[tmp] = tot;instack[tmp] = false;}}
}
void rebuild(int from, int fa, int pos, int len) {b[fa].erase(pos), b[pos].erase(fa);if (iskey[pos]) {if (from == pos) {ans[len] += 2;if (ans[len] >= 3) {puts("Yes");exit(0);}return;}c[from].emplace_back(make_pair(pos, len), ++em);c[pos].emplace_back(make_pair(from, len), em);return;}int dest = *b[pos].begin();rebuild(from, pos, dest, len + 1);
}
void dfs(int pos) {vis[pos] = true;v++, e += b[pos].size();for (auto x : b[pos])if (!vis[x]) dfs(x);
}
int F(int x) {if (f[x] == x) return x;else return f[x] = F(f[x]);
}
bool connected(int a, int b) {for (auto x : p)f[x] = x;for (auto x : p)for (auto y : c[x])if (!vise[y.second]) f[F(x)] = F(y.first.first);return F(a) == F(b);
}
void work(int pos, int from, int depth) {if (!connected(pos, from)) return;if (depth && pos == from) {if (++ans[depth] >= 3) {puts("Yes");exit(0);}return;}while (!c[pos].empty() && c[pos].back().first.first < from) c[pos].pop_back();for (unsigned i = 0; i < c[pos].size(); i++) {pair <pair <int, int>, int> x = c[pos][i];if (!vise[x.second] && !vis[x.first.first]) {vise[x.second] = vis[x.first.first] = true;work(x.first.first, from, depth + x.first.second);vise[x.second] = vis[x.first.first] = false;}}
}
int main() {read(n), read(m);for (int i = 1; i <= m; i++) {read(x[i]), read(y[i]);a[x[i]].push_back(y[i]);a[y[i]].push_back(x[i]);}for (int i = 1; i <= n; i++) {if (dfn[i] == 0) {v = 0, e = 0;tarjan(i, 0);if (e / 2 >= v + sqrt(v) + 2) {puts("Yes");return 0;}}}for (int i = 1; i <= m; i++)if (belong[x[i]] == belong[y[i]]) {b[x[i]].insert(y[i]);b[y[i]].insert(x[i]);}for (int i = 1; i <= n; i++) {iskey[i] = b[i].size() >= 3;if (!vis[i]) {v = 0, e = 0, dfs(i);if (e == 2 * v) {ans[v] += 2;if (ans[v] >= 3) {puts("Yes");return 0;}}}}for (int i = 1; i <= n; i++)if (iskey[i]) {p.push_back(i);while (!b[i].empty()) {int dest = *b[i].begin();rebuild(i, i, dest, 1);}}for (int i = 1; i <= n; i++) {sort(c[i].begin(), c[i].end());reverse(c[i].begin(), c[i].end());}memset(vis, false, sizeof(vis));for (int i = 1; i <= n; i++)if (iskey[i]) work(i, i, 0);puts("No");return 0;
}
// Cheating Solution O(Exp(N))
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXM = 1e6 + 5;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {x = 0; int f = 1;char c = getchar();for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';x *= f;
}
template <typename T> void write(T x) {if (x < 0) x = -x, putchar('-');if (x > 9) write(x / 10);putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {write(x);puts("");
}
int n, m, em, v, e, start, ans[MAXN];
int x[MAXM], y[MAXM], p[MAXN], rk[MAXN], rd[MAXN];
vector <int> a[MAXN]; set <int> b[MAXN];
vector <pair <pair <int, int>, int>> c[MAXN];
bool vis[MAXN], vise[MAXN], iskey[MAXN];bool instack[MAXN];
int tot, belong[MAXN], top, Stack[MAXN];
int timer, dfn[MAXN], low[MAXN];
bool cmp(int x, int y) {if (c[x].size() == c[y].size()) return rd[x] < rd[y];else return c[x].size() > c[y].size();
}
bool cnp(pair <pair <int, int>, int> x, pair <pair <int, int>, int> y) {if (x.first.first == y.first.first) {if (x.second == y.second) return x.first.second < y.first.second;else return x.second < y.second;} else return rk[x.first.first] < rk[y.first.first];
}
void tarjan(int pos, int fa) {low[pos] = dfn[pos] = ++timer;v++, e += a[pos].size();Stack[++top] = pos;instack[pos] = true;for (unsigned i = 0; i < a[pos].size(); i++) {if (a[pos][i] == fa) continue;if (dfn[a[pos][i]] == 0) {tarjan(a[pos][i], pos);low[pos] = min(low[pos], low[a[pos][i]]);} else if (instack[a[pos][i]]) low[pos] = min(low[pos], dfn[a[pos][i]]);}if (low[pos] == dfn[pos]) {int tmp = Stack[top--];belong[tmp] = ++tot;instack[tmp] = false;while (tmp != pos) {tmp = Stack[top--];belong[tmp] = tot;instack[tmp] = false;}}
}
void rebuild(int from, int fa, int pos, int len) {b[fa].erase(pos), b[pos].erase(fa);if (iskey[pos]) {if (from == pos) {ans[len] += 2;if (ans[len] >= 3) {puts("Yes");exit(0);}return;}c[from].emplace_back(make_pair(pos, len), ++em);c[pos].emplace_back(make_pair(from, len), em);return;}int dest = *b[pos].begin();rebuild(from, pos, dest, len + 1);
}
void dfs(int pos) {vis[pos] = true;v++, e += b[pos].size();for (auto x : b[pos])if (!vis[x]) dfs(x);
}
void work(int pos, int from, int depth) {if (depth && pos == from) {if (++ans[depth] >= 3) {puts("Yes");exit(0);}return;}if ((clock() - start) >= 1.5 * CLOCKS_PER_SEC) {puts("No");exit(0);}while (!c[pos].empty() && rk[c[pos].back().first.first] < rk[from]) c[pos].pop_back();for (unsigned i = 0; i < c[pos].size(); i++) {pair <pair <int, int>, int> x = c[pos][i];if (!vise[x.second] && !vis[x.first.first]) {vise[x.second] = vis[x.first.first] = true;work(x.first.first, from, depth + x.first.second);vise[x.second] = vis[x.first.first] = false;}}
}
int main() {read(n), read(m), start = clock();for (int i = 1; i <= m; i++) {read(x[i]), read(y[i]);a[x[i]].push_back(y[i]);a[y[i]].push_back(x[i]);}for (int i = 1; i <= n; i++) {if (dfn[i] == 0) {v = 0, e = 0;tarjan(i, 0);if (e / 2 >= v + sqrt(v) + 2) {puts("Yes");return 0;}}}for (int i = 1; i <= m; i++)if (belong[x[i]] == belong[y[i]]) {b[x[i]].insert(y[i]);b[y[i]].insert(x[i]);}for (int i = 1; i <= n; i++) {iskey[i] = b[i].size() >= 3;if (!vis[i]) {v = 0, e = 0, dfs(i);if (e == 2 * v) {ans[v] += 2;if (ans[v] >= 3) {puts("Yes");return 0;}}}}for (int i = 1; i <= n; i++)if (iskey[i]) {while (!b[i].empty()) {int dest = *b[i].begin();rebuild(i, i, dest, 1);}}for (int i = 1; i <= n; i++)p[i] = i, rd[i] = i;random_shuffle(rd + 1, rd + n + 1);sort(p + 1, p + n + 1, cmp);for (int i = 1; i <= n; i++)rk[p[i]] = i;for (int i = 1; i <= n; i++) {sort(c[i].begin(), c[i].end(), cnp);reverse(c[i].begin(), c[i].end());}memset(vis, false, sizeof(vis));for (int i = 1; i <= n; i++)work(p[i], p[i], 0);puts("No");return 0;
}

【LOJ3077】「2019 集训队互测 Day 4」绝目编诗相关推荐

  1. Loj#3077-「2019 集训队互测 Day 4」绝目编诗【结论,虚树,鸽笼原理】

    正题 题目链接:https://loj.ac/p/3077 题目大意 给出nnn个点mmm条边的一张简单无向图,求是否存在两个长度相等的简单环. 1≤n≤104,1≤m≤1061\leq n\leq ...

  2. 「2019 集训队互测 Day 1」最短路径 解题报告

    一.题目概述 题目链接:Libre OJ. 给出一张图,求出 ans=∑i=1n∑j=1n[i≠j]dk(i,j)ans=\sum_{i=1}^n\sum_{j=1}^n[i\ne j]\texttt ...

  3. 「LOJ2474」「2018 集训队互测」北校门外的未来-笛卡尔树及其扩展+LCT

    Description 链接 Solution 对于一棵树 TTT,定义其的笛卡尔树 C(T)C(T)C(T) 满足: 堆性质,即祖先的权值(本题中为标号)一定大于子孙的权值. 搜索树性质,即任意子树 ...

  4. UOJ#191. 【集训队互测2016】Unknown

    UOJ#191. [集训队互测2016]Unknown 题目描述 Solution 二进制分组. 每一个组内维护一个斜率单调减的凸包. 因为有删点,避免出现反复横跳产生的爆炸复杂度,需要等到同一深度的 ...

  5. [2015国家集训队互测]口胡

    比赛链接 http://uoj.ac/contest/11 口胡题解 A.[集训队互测2015]Robot 直接果断打暴力了...这个暴力很好写,我就不废话了 B.[集训队互测2015]Marketi ...

  6. 【集训队互测2015】最大异或和

    首先不知道有没有神仙线段树分治过的. 首先一个较为显然的性质: \[ \mathrm{Span}\{v_1, v_2, \dots, v_n\} = \mathrm{Span}\{v_1, v_2 - ...

  7. 洛谷 P4463 [集训队互测 2012] calc(拉格朗日插值优化DP)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/P4463 Prob ...

  8. 【uoj#94】【集训队互测2015】胡策的统计(集合幂级数)

    题目传送门:http://uoj.ac/problem/94 这是一道集合幂级数的入门题目.我们先考虑求出每个点集的连通生成子图个数,记为$g_S$,再记$h_S$为点集$S$的生成子图个数,容易发现 ...

  9. BZOJ3938 UOJ88:[集训队互测2015]Robot——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3938 http://uoj.ac/problem/88 小q有n只机器人,一开始他把机器人放在了一 ...

最新文章

  1. SparkSQL ThriftServer 安全相关功能的现状分析
  2. C#设计模式(23种设计模式)
  3. python3对urllib和urllib2进行了重构
  4. Android拍照流程
  5. 同一个项目相互调接口_408计算机网络D3-第二章:网络体系结构与参考模型(上)分层结构-协议-接口-服务...
  6. 常见的设计模式--单例模式
  7. quercus mysql_让PHP运行在Glassfish中:quercus配置
  8. c语言鼠标环绕特效,C语言写的鼠标有残影,急需解决方案,在线等待!
  9. nginx php 防止跨站,Nginx下多网站单独php-fpm进程目录权限防跨站
  10. 看完阿里的代码规范,立马学会代码分层,再也不会被同事怼
  11. 环境搭建-CentOS集群搭建
  12. 基于深度学习的目标检测
  13. exls下载后显示jsp_jsp笔记
  14. 计算机网络下一跳IP,计算机网络之IP地址
  15. tcp 压力 测试 软件,强大的TcpServer压力测试工具及源码(附突破连接限制的方法和工具)...
  16. 存储器容量计算及相关概念
  17. SKU与SPU的区别与联系
  18. 火爆全网的 Evil.js 源码解读
  19. 第14章 Beta测试
  20. 拆解理想汽车Q3财报:收入增速继续下滑,年内两次更换首席技术官

热门文章

  1. dpdk 网卡初始化时中断使能的过程
  2. 基于单片机智能温室大棚控制系统
  3. ORACLE根据日期获取季度,并获取季度的第一天,以及季度的第一个月
  4. 【语音分析】语音信号分析含Matlab源码
  5. 电脑杂乱 -- 自带赘余QQWeChat
  6. hdu7244-Winner Prediction(22多校第十场1001 dinic最大流)
  7. 用dw写php怎么运行,dw怎么运行php程序?
  8. 计算机组成ldi指令码,计算机组成原理 实验报告四(含答案).docx
  9. 免安装ABBYY FineReader 12
  10. 真正解决问题:maven eclipse tomcat java.lang.ClassNotFoundException: org.springframework.web.context.Contex