CF652E Pursuit For Aritifacts
这是一道很好的练习强联通的题目。 首先,从题中可以看到,题目的要求就是要我们求出从起点到终点是否可以经过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的更多相关文章
- Robust PCA via Outlier Pursuit
目录 引 主要结果 定理1 定理2 理论证明 构造Oracle Problem 算法 Xu H, Caramanis C, Sanghavi S, et al. Robust PCA via Outl ...
- Subway Pursuit (二分)(交互题)
题目来源:codeforces1039B Subway Pursuit 题目大意: 在1到n里有一个运动的点,要求找到这个点,每次可以查询一个区间内有没有这个点,每次这个点往左或者往右移动1到k个位置 ...
- 观后感|当幸福来敲门 The Pursuit of Happyness
更好的阅读体验请点击:当幸福来敲门 The Pursuit of Happyness 看到时光机点亮的那一刻,我想儿子克里斯托夫正在侏罗纪的世界内探险,看着山川河流,穿梭在恐龙的脚下,在山洞中安稳的度 ...
- Pursuit For Artifacts CodeForces - 652E (Tarjan+dfs)
Pursuit For Artifacts CodeForces - 652E Johnny is playing a well-known computer game. The game are i ...
- Projection Pursuit Regression----读书笔记
The central idea is to extract linear combinations of the inputs as derived features, and then model ...
- codeforces 652E Pursuit For Artifacts 边双连通分量
题意:n个点,m条边的无向图,有的边上有标记,每条边只能走一次 给你一个起点,一个终点,询问是否能找到从起点到终点的路径,这条路径至少包含一条含有标记的边 分析:然后边双缩点 下面介绍一下边双的性质 ...
- codeforces 652E . Pursuit For Artifacts 强连通分量
题目链接 题目大意: 给一个图, n个点m条边, 某些边上面有权值. 一条边只能走一次, 给两个点s, t. 问你, 从s到t能否经过有权值的边. 首先肯定要缩点, 然后看同一个连通分量里面的边, 是 ...
- Educational Codeforces Round 10 E - Pursuit For Artifacts (强联通缩点 + 回溯)
题目链接:http://codeforces.com/contest/652/problem/E 给你n个点m个边,x和y双向连接,要是z是1表示这条边上有宝藏,0则没有,最后给你起点和终点,问你要是 ...
- Pursuit For Artifacts CodeForces - 652E
https://vjudge.net/problem/CodeForces-652E 边双啊,就是点双那个tarjan里面,如果low[v]==dfn[v](等同于low[v]>dfn[u]), ...
随机推荐
- python(面向对象-类封装调用)
一.面对对象思想 (1)大家肯定听过 Python 中”一切皆对象“的说法,但可能并不了解它的具体含义,只是在学习的时候听说 Python 是面向对象的编程语言,本节将向大家详细介绍 Python 面 ...
- IIS 搭网站(一)
搭建类型win+IIs+asp+access(一) 第一步首先保证虚拟机的系统软盘是连接状态,如下图状态即可 第二步: 第三步: 第四步: 第五步: 第六步:这个时候就会自动搜索软盘里面的数据自动安装 ...
- Flutter 打包Android APK 笔记与事项
获取一个KEY 首先要获取 你的 打包应用的一个 key ,这一步其实和 在AndroidStudio 上打包 APK 一样,都是要注册一个本地的 key,key 其实也就是 jks文件啦. 如果已经 ...
- docker部署gitlab
Docker部署gitlab 一.前提条件 (1) 存在docker (2) 服务器可以联网(外网) (3) 服务器内存至少4G(内存不够会出现502错误) 内存不足502错误 ...
- Jenkins如何进行权限管理
一.安装插件 插件名:Role-based Authorization Strategy 二.配置授权策略 三.创建用户 四.添加并配置权限 4.1.添加Global Role 普通角色拥有全局只读权 ...
- E. Kamil and Making a Stream 区间gcd
E. Kamil and Making a Stream 这个题目要用到一个结论,就是区间一个区间长度为n的不同的gcd不会超过logn 个, 其实就是知道这个题目可以暴力就好了. 然后就是对于每一个 ...
- (1).Mybatis的创建。配置。映射。dao映射
https://www.cnblogs.com/zxdup/ 一.Mybatis的创建 1.创建一个新的项目,建议选 Empty Project(空项目), 之后回跳转到Project Structu ...
- docker-compose安装rabbitmq
编写时间:2020-05-08 参考文档:docker安装rabbitmq 1. 编写docker-compose.yml version: '3' services: rabbitmq: image ...
- Coursera课程笔记----Write Professional Emails in English----Week 4
Request and Apology Emails(Week 4) How to Write Request Emails Write more POLITELY & SINCERELUY ...
- vue项目-打印页面中指定区域的内容(亲测有效!)
关于打印整个页面的,没什么好说的.今天我给大家分享一个打印指定区域的方法,你想打印哪里,就打印哪里! 我也是刚刚开始接触打印这一块功能的,然后当然是找度娘深入了解了一番啦,期间试了网上的各种方法,有的 ...