题目传送门

这是一道很好的练习强联通的题目。 首先,从题中可以看到,题目的要求就是要我们求出从起点到终点是否可以经过flag = 1 的边。 由于是无向图,且要求很多,直接暴力dfs会很凌乱。

那么,我们就想到一个思路:能不能尽量把这张图缩小,标记转为点,最好成为一条一条链呢?

tarjan的缩点!!

没错,对于一个环,可以想到,只要这个环中有一条边flag = 1,那么所有的点我们都可以通过falg = 1的边到达(因为这是环)。所以,不妨进行tarjan缩点,只要这个缩点中有一条边falg = 1,我们就把这个缩点打上tag。

再一想,经过缩点之后,原来十分凌乱的图就变成了一棵树。到达终点的路线也就只有固定一条了。这里我选择dfs。

思路大体就是这样,总时间复杂度O(M + N)

话不多说,具体细节操作标记在代码里面了。

#include<bits/stdc++.h>
using namespace std;
#define N 500010
#define isdigit(c) ((c)>='0'&&(c)<='9') inline int read(){
int x = ,s = ;
char c = getchar();
while(!isdigit(c)){
if(c == '-') s = -;
c = getchar();
}
while(isdigit(c)){
x = (x << ) + (x << ) + (c ^ '');
c = getchar();
}
return x * s;
} int n, m;
struct node{
int u, v, flag;
int next;
} t[N << ];
int f[N];//日常邻接表 int s, ht;//起点, 终点
int dfn[N], low[N], scc[N]; //scc即为缩点后每个缩点的编号
stack <int> stac;//缩点用的
bool vis[N];//一个点是否被经过 int bian = ;
void add(int u, int v, int flag){
bian++;
t[bian].u = u;
t[bian].v = v;
t[bian].flag = flag;
t[bian].next = f[u];
f[u] = bian;
return ;
} int cnt = , cac;//cac为强联通的数量
void tarjan(int now, int fa){//无向图的tarjan强联通 板子
dfn[now] = low[now] = ++cnt;
vis[now] = ;
stac.push(now);
for(int i = f[now]; i;i = t[i].next){
int v = t[i].v;
if(v != fa){
if(!dfn[v]){
tarjan(v, now);
low[now] = min(low[now], low[v]);
}
else if(vis[v])low[now] = min(low[now], low[v]);
}
}
if(dfn[now] == low[now]){
int cur;
cac++;
do{
cur = stac.top();
stac.pop();
scc[cur] = cac;
vis[cur] = ;
}while(cur != now);
}
return ;
} bool tong[N]; //tong为每个缩点被打上的标记,即上文所说的,是否包含flag = 1的边
void dfs(int now, bool flag){
if(tong[now])flag = ;//这个缩点标记为1的话,记下来
if(now == scc[ht]){
if(flag)puts("YES");//搜到终点,没什么好说的
else puts("NO");
return ;
}
for(int i = f[now]; i;i = t[i].next){
int v = t[i].v, u = t[i].u;
if(!vis[v]){
vis[v] = ;
dfs(v, flag | t[i].flag);//这里要注意不要漏掉了缩点与缩点之间的边的 flag
}
}
return ;
} int main(){
n = read(), m = read();
for(int i = ;i <= m; i++){
int x = read(), y = read(), tag = read();
add(x, y, tag);add(y, x, tag);
}
s = read() , ht = read();
tarjan(, );
for(int i = ;i <= bian; i += ){
if(scc[t[i].u] == scc[t[i].v] && t[i].flag){
tong[scc[t[i].u]] = ;//为强联通分量中的边,且flag = 1
}
}
memset(f, , sizeof(f));//重复利用
bian = ;
memset(vis, , sizeof(vis));
for(int i = ;i <= m << ; i++){
int u = t[i].u, v = t[i].v;
if(scc[u] != scc[v]){
add(scc[u], scc[v], t[i].flag);//不同缩点之间的连边,需要保留。flag不能改
}
}
vis[scc[s]] = ;
dfs(scc[s], );//dfs的都是缩点,这点不要忘了
return ;
}

CF652E Pursuit For Aritifacts的更多相关文章

  1. Robust PCA via Outlier Pursuit

    目录 引 主要结果 定理1 定理2 理论证明 构造Oracle Problem 算法 Xu H, Caramanis C, Sanghavi S, et al. Robust PCA via Outl ...

  2. Subway Pursuit (二分)(交互题)

    题目来源:codeforces1039B Subway Pursuit 题目大意: 在1到n里有一个运动的点,要求找到这个点,每次可以查询一个区间内有没有这个点,每次这个点往左或者往右移动1到k个位置 ...

  3. 观后感|当幸福来敲门 The Pursuit of Happyness

    更好的阅读体验请点击:当幸福来敲门 The Pursuit of Happyness 看到时光机点亮的那一刻,我想儿子克里斯托夫正在侏罗纪的世界内探险,看着山川河流,穿梭在恐龙的脚下,在山洞中安稳的度 ...

  4. Pursuit For Artifacts CodeForces - 652E (Tarjan+dfs)

    Pursuit For Artifacts CodeForces - 652E Johnny is playing a well-known computer game. The game are i ...

  5. Projection Pursuit Regression----读书笔记

    The central idea is to extract linear combinations of the inputs as derived features, and then model ...

  6. codeforces 652E Pursuit For Artifacts 边双连通分量

    题意:n个点,m条边的无向图,有的边上有标记,每条边只能走一次 给你一个起点,一个终点,询问是否能找到从起点到终点的路径,这条路径至少包含一条含有标记的边 分析:然后边双缩点 下面介绍一下边双的性质 ...

  7. codeforces 652E . Pursuit For Artifacts 强连通分量

    题目链接 题目大意: 给一个图, n个点m条边, 某些边上面有权值. 一条边只能走一次, 给两个点s, t. 问你, 从s到t能否经过有权值的边. 首先肯定要缩点, 然后看同一个连通分量里面的边, 是 ...

  8. Educational Codeforces Round 10 E - Pursuit For Artifacts (强联通缩点 + 回溯)

    题目链接:http://codeforces.com/contest/652/problem/E 给你n个点m个边,x和y双向连接,要是z是1表示这条边上有宝藏,0则没有,最后给你起点和终点,问你要是 ...

  9. Pursuit For Artifacts CodeForces - 652E

    https://vjudge.net/problem/CodeForces-652E 边双啊,就是点双那个tarjan里面,如果low[v]==dfn[v](等同于low[v]>dfn[u]), ...

随机推荐

  1. Unity 游戏框架搭建 2019 (四十二、四十三) MonoBehaviour 简化 & 定时功能

    MonoBehaviour 简化 在前两篇,我们完成了第九个示例.为了完善第九个示例,我们复习了类的继承,又学习了泛型和 params 关键字. 我们已经接触了类的继承了.接触继承之前,把类仅仅当做是 ...

  2. RDP凭据离线脱取

    内网渗透-获取本地RDP密码 获取RDP 连接记录: reg query "HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Clie ...

  3. java基础篇 之 非静态内部类

    什么是非静态内部类: public class Outer { Outer() { System.out.println("我是外部类"); } class Inner { Inn ...

  4. Synchronized 和 ReentrantLock (Lock )的区别

    原始构成 Synchronized 是关键字,属于JVM层面,底层是通过 monitorenter 和 monitorexit 完成,依赖于 monitor 对象来完成.由于 wait/notify ...

  5. 在windows环境里,用Docker搭建Redis开发环境(新书第一个章节)

    大家都知道高并发分布式组件的重要性,而且如果要进大厂,这些技术不可或缺.但这些技术的学习难点在于,大多数项目里的分布式组件,都是搭建在Linux系统上,在自己的windows机器上很难搭建开发环境,如 ...

  6. 【matlab系列汇总】小白博主的matlab学习实战快速进阶之路(持续更新)

    我把之前在学习和工作中使用matlab的技巧和使用教程等相关整理到这里,方便查阅学习,如果能帮助到您,请帮忙点个赞: MATLAB可以进行矩阵运算.绘制函数和数据.实现算法.创建用户界面.连接其他编程 ...

  7. Battery Charging Specification Revision 1.2 中文版本

    Battery Charging Specification Revision 1.2 Li,Guanglei 2014.04.03 Rev0.1 转载请注明转自:http://blog.csdn.n ...

  8. Power Query:非常规工资条

    常规工资条为标题.内容.空行,每三行一循环,横向排版.打印.空行填充颜色,方便切割.其中用到函数嵌套,先把table以row转换为list,然后用List.TransformMany生成Table.C ...

  9. .netcore 部署时遇到413 Request Entity Too Large 和 413Payload Too Large 的问题

    .netcore3.1 遇到一个webapi 上传大文件问题 首先,在kestrel模式调试模式下上传 会报错413, 需要在三个地方添加 1.startup中 这里设置的2g最大值 2.在progr ...

  10. Redis学习笔记(六) 对象

    前面我们看了Redis用到的主要数据结构,如简单动态字符串(SDS).双向链表.字典.压缩列表.整数集合等. 但是Redis并没有直接使用这些数据结构来实现键值对,而是基于这些数据结构创建了一个对象系 ...