[P2416 泡芙] 题解报告
题目链接:P2416 泡芙
简化题意
给定一个无向图 \(G\),每条边有边权 \(0 / 1\),现给定 \(m\) 组询问,每次询问形如 \(s, t\),问是否可以从 \(s\) 走到 \(t\),边权和为正数且不会重复经过一条边。
题目分析
本题可以使用 tarjan 算法。
可以想一下,如果在从 \(s\) 到 \(t\) 的路径上有一个环,那么我们一定会选择经过这个环。因为走完整条环之后可以回到起点,不会重复经过某一条路,而且还有可能多加一点边权。
因此考虑缩点。使用 tarjan 算法将所有边双连通分量缩成点。
边权转点权时,设有边 \((u, v)\),边权为 \(1\) ,那么可以新建一个节点,将边权存在这个点的点权上。
如下图:
缩点时将每个新点的点权设成连通分量内所有点的点权的或,换言之,就是设置成“连通分量内是否有点权为 \(1\) 的点 (若有则为 \(1\),否则为 \(0\))”。
缩点之后图会变成一棵树。之后 \(m\) 次操作就是询问从 \(u\) 到 \(v\) 两个点之间的路径权值和是否大于等于 \(1\),可以使用树上差分解决。
时间复杂度大概是 \(O(m + Q \log n)\) 的样子。跑的大概没有题解里的其他 dalao 快
CODE
// Author:Lcy
// Date:2022.07.15
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 300010;
int n, m;
int h[N << 1], e[N << 2], ne[N << 2], w[N << 1], idx = 1;
int stk[N << 1], timestamp, top;
int dfn[N << 1], low[N << 1], val[N << 1];
int color[N << 1];
int cnt, fa[N << 1], dep[N << 1], sz[N << 1];
int son[N << 1], s[N << 1], Top[N << 1], id[N << 1];
int from[N], to[N];
void add(int a, int b)
{
e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
}
void tarjan(int u, int from)
{
dfn[u] = low[u] = ++ timestamp;
stk[ ++ top] = u;
for (int i = h[u]; i; i = ne[i])
{
int j = e[i];
if (!dfn[j]) {
tarjan(j, i);
low[u] = min(low[u], low[j]);
}
else if (i != (from ^ 1))
low[u] = min(low[u], dfn[j]);
}
if (dfn[u] == low[u])
{
cnt ++ ;
int y;
do {
y = stk[top -- ];
val[cnt] |= w[y];
color[y] = cnt;
} while (y != u);
}
}
void dfs1(int u, int father, int depth)
{
fa[u] = father, dep[u] = depth, sz[u] = 1;
s[u] = s[fa[u]] + (val[u] == 1);
for (int i = h[u]; i; i = ne[i])
{
int j = e[i];
if (j == father) continue;
dfs1(j, u, depth + 1);
sz[u] += sz[j];
if (sz[son[u]] < sz[j]) son[u] = j;
}
}
void dfs2(int u, int t)
{
Top[u] = t, id[u] = ++ cnt;
if (!son[u]) return;
dfs2(son[u], t);
for (int i = h[u]; i; i = ne[i])
{
int j = e[i];
if (j == fa[u] || j == son[u]) continue;
dfs2(j, j);
}
}
int lca(int u, int v)
{
while (Top[u] != Top[v])
{
if (dep[Top[u]] <= dep[Top[v]]) swap(u, v);
u = fa[Top[u]];
}
if (dep[u] > dep[v]) swap(u, v);
return u;
}
bool query(int u, int v)
{
int LCA = lca(u, v);
return (s[u] - s[LCA] + s[v] - s[LCA] + val[LCA]);
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i ++ )
{
int z;
scanf("%d%d%d", &from[i], &to[i], &z);
add(from[i], n + i), add(n + i, from[i]);
add(n + i, to[i]), add(to[i], n + i);
w[n + i] = z;
}
tarjan(1, -1);
memset(h, 0, sizeof h);
memset(e, 0, sizeof e);
memset(ne, 0, sizeof ne);
idx = 0;
for (int i = 1; i <= m; i ++ ) {
if (color[from[i]] != color[n + i])
add(color[from[i]], color[n + i]),
add(color[n + i], color[from[i]]);
if (color[to[i]] != color[n + i])
add(color[to[i]], color[n + i]),
add(color[n + i], color[to[i]]);
}
dfs1(1, -1, 1), dfs2(1, 1);
int Q;
scanf("%d", &Q);
while (Q -- )
{
int u, v;
scanf("%d%d", &u, &v);
(query(color[u], color[v])) ? (puts("YES")) : (puts("NO"));
}
return 0;
}
[P2416 泡芙] 题解报告的更多相关文章
- 2015浙江财经大学ACM有奖周赛(一) 题解报告
2015浙江财经大学ACM有奖周赛(一) 题解报告 命题:丽丽&&黑鸡 这是命题者原话. 题目涉及的知识面比较广泛,有深度优先搜索.广度优先搜索.数学题.几何题.贪心算法.枚举.二进制 ...
- cojs 强连通图计数1-2 题解报告
OwO 题目含义都是一样的,只是数据范围扩大了 对于n<=7的问题,我们直接暴力搜索就可以了 对于n<=1000的问题,我们不难联想到<主旋律>这一道题 没错,只需要把方程改一 ...
- cojs 二分图计数问题1-3 题解报告
OwO 良心的FFT练手题,包含了所有的多项式基本运算呢 其中一部分解法参考了myy的uoj的blog 二分图计数 1: 实际是求所有图的二分图染色方案和 我们不妨枚举这个图中有多少个黑点 在n个点中 ...
- 题解报告:hdu 1398 Square Coins(母函数或dp)
Problem Description People in Silverland use square coins. Not only they have square shapes but also ...
- 题解报告:hdu 2069 Coin Change(暴力orDP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2069 Problem Description Suppose there are 5 types of ...
- 题解报告:hdu 1028 Ignatius and the Princess III(母函数or计数DP)
Problem Description "Well, it seems the first problem is too easy. I will let you know how fool ...
- CF Educational Round 78 (Div2)题解报告A~E
CF Educational Round 78 (Div2)题解报告A~E A:Two Rival Students 依题意模拟即可 #include<bits/stdc++.h> us ...
- CF1169(div2)题解报告
CF1169(div2)题解报告 A 不管 B 首先可以证明,如果存在解 其中必定有一个数的出现次数大于等于\(\frac{m}{2}\) 暴力枚举所有出现次数大于等于$\frac{m}{2} $的数 ...
- CFEducational Codeforces Round 66题解报告
CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第 ...
- CF Round #580(div2)题解报告
CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...
随机推荐
- 高可用mongodb集群(分片+副本):性能测试
目录 ■ 为指定的库和表指定hash分片 ■ 测试模型,即workload模型 ■ 测试指标 ■ workload_s6 ■ 分片集群性能测试数据统计分析 ■ 测试结论 Yahoo! Cloud Se ...
- 将GitBash设置为VS Code的默认终端
这个东西搞了半天,真的无语...网上的东西都太旧了 注意:"terminal.integrated.shell.windows"自2021年4月起已弃用. 1.首先打开设置 2.进 ...
- ExtJS的使用方法汇总(1)——配置和表格控件使用
在网上差一些关于ExtJS的相关资料,看到这篇博客写的不错,拿出来分享一下! 博客文章:ExtJS的使用方法汇总(1)--配置和表格控件使用 ExtJS的使用方法汇总(2)- ...
- select...for update到底是加了行锁,还是表锁?
前言 前几天,知识星球中的一个小伙伴,问了我一个问题:在MySQL中,事务A中使用select...for update where id=1锁住了,某一条数据,事务还没提交,此时,事务B中去用sel ...
- 火山引擎 ByteHouse:只需 2 个方法,增强 ClickHouse 数据导入能力
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 作为企业数字化建设的必备要素,易用的数据引擎能帮助企业提升数据使用效率,更好提升数据应用价值,夯实数字化建设基础. ...
- Gson替换掉多漏洞的FastJson
添加依赖: <!-- gson --> <dependency> <groupId>com.google.code.gson</groupId> < ...
- Isito 入门(八):金丝雀发布
本教程已加入 Istio 系列:https://istio.whuanle.cn 目录 6,金丝雀发布 金丝雀发布 按照流量比例划分 按照 Header 划分 6,金丝雀发布 项目总是处于不断变化之中 ...
- KubeEdge-Ianvs v0.2 发布:终身学习支持非结构化场景
本文分享自华为云社区<KubeEdge-Ianvs v0.2 发布:终身学习支持非结构化场景>,作者: 云容器大未来. 在边缘计算的浪潮中,AI是边缘云乃至分布式云中最重要的应用.随着边缘 ...
- 使用openpyxl库读取Excel文件数据
在Python中,我们经常需要读取和处理Excel文件中的数据.openpyxl是一个功能强大的库,可以轻松地实现Excel文件的读写操作.本文将介绍如何使用openpyxl库读取Excel文件中的数 ...
- 【MISC】[MoeCTF 2022]cccrrc --crc32爆破
附件下载下来为压缩包,需要密码,查看该压缩包的内容 此处发现里面四个txt文件均已被加密,但是每个txt的内容都只有四个字节,符合crc32爆破条件,直接上脚本: import binascii im ...