【洛谷2416】泡芙(Tarjan+LCA)
题目描述
火星猫经过一番努力终于到达了冥王星。他发现冥王星有 \(N\) 座城市,\(M\) 条无向边。火星猫准备出发去找冥王兔,他听说有若干泡芙掉落在一些边上,他准备采集一些去送给冥王兔。但是火星猫的火星光环和冥王星相生相克,当火星猫走过一条路之后,这条路就不能再走了。如果冥王兔吃不到泡芙,他们就不能嘿嘿嘿了。所以告诉你火星猫和冥王兔的位置,请问冥王兔能不能吃到泡芙。
输入输出格式
输入格式:
第一行 \(N,M\) 表示点数和边数。
接下来 \(M\) 行每行 \(X,Y,Z\) 表示 $ X $ 到 \(Y\) 有一条无向边,\(Z=1\) 表示有泡芙,\(Z=0\) 表示没有
接下来一行是 \(Q\),表示有 \(Q\)组询问。
每行 \(S,T\) 表示火星猫和冥王兔的位置。
输出格式:
对于每组询问输出 \(YES\) 或 \(NO\)
输入输出样例
输入样例#1:
6 7
1 2 0
2 3 0
3 1 0
3 4 1
4 5 0
5 6 0
6 4 0
1
1 6
输出样例#1:
YES
说明
\(NO.\) | \(N\leq\) | \(M\leq\) | \(Q\leq\) | 备注 |
---|---|---|---|---|
\(1-4\) | \(1000\) | \(N-1\) | \(50000\) | 保证图是一棵树 |
\(5-8\) | \(300000\) | \(N-1\) | \(300000\) | 保证图是一棵树 |
\(9-10\) | \(20\) | \(50\) | \(5\) | 无 |
\(11-14\) | \(1000\) | \(5000\) | \(50000\) | 无 |
\(15-20\) | \(300000\) | \(300000\) | \(300000\) | 无 |
题解
一道我喜欢的\(LCA+Tarjan\)的题
首先,我们发现若进入了一个环,我们一定可以收集到环上的泡芙(环嘛,可以两边走),若还有出边,则可以出去。
所以,第一步\(Tarjan\)缩点,并收集每个环中的信息,去建一个新图。
我们会发现新建的图是一个有点权和边权的图,因为无环,所以也是一棵树。
所以可以用\(LCA\)求出两点之间的最短路径,并记录路径上是否泡芙。
思维量不大,但细节较多,争取自己实现。
code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cctype>
#define ll long long
#define R register
#define N 300005
using namespace std;
template<typename T>inline void read(T &a){
char c=getchar();T x=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
a=f*x;
}
int n,m,q,u[N],v[N],w[N],h[N],tot,fa[N][22],dep[N],dis[N][22];
int top,num,sta[N],dfn[N],low[N],vis[N],cnt,col[N],val[N];
struct node{
int nex,to,dis;
}edge[N<<1];
inline void add(R int u,R int v,R int w){
edge[++tot].nex=h[u];
edge[tot].to=v;
edge[tot].dis=w;
h[u]=tot;
}
inline void tarjan(R int x,R int f){
dfn[x]=low[x]=++num;
sta[++top]=x;vis[x]=1;
for(R int i=h[x];i;i=edge[i].nex){
R int xx=edge[i].to;
if(xx==f)continue;
if(!dfn[xx]){
tarjan(xx,x);
low[x]=min(low[x],low[xx]);
}
else if(vis[xx])low[x]=min(low[x],dfn[xx]);
}
if(dfn[x]==low[x]){
R int now=-1;
cnt++;
while(now!=x){
now=sta[top];
top--;
col[now]=cnt;
vis[now]=0;
}
}
}
inline void dfs(R int x,R int f,R int g){
dep[x]=dep[f]+1;fa[x][0]=f;dis[x][0]=g+val[x];
for(R int i=1;(1<<i)<=dep[x];i++)
fa[x][i]=fa[fa[x][i-1]][i-1],
dis[x][i]=dis[fa[x][i-1]][i-1]+dis[x][i-1];
for(R int i=h[x];i;i=edge[i].nex){
R int xx=edge[i].to;
if(xx==f)continue;
dfs(xx,x,edge[i].dis);
}
}
inline int lca(R int x,R int y){
R int res=0;
if(dep[x]>dep[y])swap(x,y);
for(R int i=20;i>=0;i--)
if(dep[x]<=dep[y]-(1<<i))res+=dis[y][i],y=fa[y][i];
if(x==y)return res+val[x];
for(R int i=20;i>=0;i--)
if(fa[x][i]!=fa[y][i])
res+=dis[x][i],res+=dis[y][i],
x=fa[x][i],y=fa[y][i];
res+=dis[x][0]+dis[y][0]+val[fa[x][0]];
return res;
}
int main(){
read(n);read(m);
for(R int i=1;i<=m;i++){
read(u[i]);read(v[i]);read(w[i]);
add(u[i],v[i],w[i]);add(v[i],u[i],w[i]);
}
for(R int i=1;i<=n;i++)
if(!dfn[i])tarjan(i,0);
memset(h,0,sizeof(h));tot=0;
for(R int i=1;i<=m;i++){
if(col[u[i]]==col[v[i]])
val[col[u[i]]]+=w[i];
if(col[u[i]]!=col[v[i]])
add(col[u[i]],col[v[i]],w[i]),add(col[v[i]],col[u[i]],w[i]);
}
dfs(1,0,0);
read(q);
while(q--){
R int x,y;
read(x);read(y);
x=col[x],y=col[y];
if(lca(x,y))printf("YES\n");
else printf("NO\n");
}
return 0;
}
【洛谷2416】泡芙(Tarjan+LCA)的更多相关文章
- 【倍增】洛谷P3379 倍增求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 【RMQ】洛谷P3379 RMQ求LCA
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- 洛谷P2680 运输计划 [LCA,树上差分,二分答案]
题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...
- 【洛谷 P4211】[LNOI2014]LCA(树链剖分,差分)
题目链接 看到题目肯定首先想到要求LCA(其实是我菜),可乍一看,n与q的规模为5W, 求LCA的复杂度为\(O(logN)\),那么总时间复杂度为\(O(nq\ log\ n)\). 怎么搞呢? 会 ...
- 2019/5/13 洛谷P4742 【tarjan缩点 + 拓扑dp】
题目链接:https://www.luogu.org/problemnew/show/P4742 题目大意:给一张有向图, 每个点都有点权,第一次经过该点时,该点的点权有贡献,求这张图上一条路径(终点 ...
- 洛谷P-4782 2-sat+Tarjan
https://www.luogu.org/problemnew/solution/P4782 这里的大佬已经说的够好了 #include<iostream> #include<cs ...
- AC日记——信息传递 洛谷 P2661 (tarjan求环)
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 洛谷 P1967 货车运输 LCA + 最小生成树
两点之间边权最大值的最小值一定在图的最小生成树中取到. 求出最小生成树,进行倍增即可. Code: #include<cstdio> #include<algorithm> u ...
- 洛谷 1262 间谍网络 Tarjan 图论
洛谷 1262 图论 tarjan 并不感觉把这道题目放在图的遍历中很合适,虽然思路比较简单但是代码还是有点多的,, 将可收买的间谍的cost值设为它的价格,不可购买的设为inf,按照控制关系连图,T ...
随机推荐
- 最长公共子序列(lcs)
给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符 ...
- Vulkan Tutorial 09 图像与视图
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 使用任何的VkImage,包括在交换链或者渲染管线中的,我们都需要创建VkImage ...
- itemize,enumerate,description 用法【LaTeX 使用】
itemize和enumerate还有description 是LaTeX里列举的三种样式,分别讲一些使用技巧.itemize(意为分条目):\begin{itemize}\item[*] a\ite ...
- linux驱动模块编译(初学者)
inux 模块编译步骤(转) 本文将直接了当的带你进入linux的模块编译.当然在介绍的过程当中,我也会添加一些必要的注释,以便初学者能够看懂.之所以要写这篇文章,主要是因为从书本上学的话,可能要花更 ...
- 配置环境是程序员的第一步 -- Windows 10 下 MySQL 安装
MySQL 作为最典型的关系型数据库管理系统,由于其体积小.速度快.总体拥有成本低,尤其是其开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库.MySQL 社区版的功能也足够我们 ...
- TTS技术
一.简介 TTS技术,TTS是Text To Speech的缩写,即"从文本到语音".它将计算机自己产生的.或外部输入的文字信息转变为可以听得懂的.流利的汉语口语(或者其他语言语音 ...
- 16.数据类型(data_type)
CREATE TABLE 语句 CREATE TABLE 语句用于创建数据库中的表. SQL CREATE TABLE 语法 CREATE TABLE 表名称 ( 列名称1 数据类型, 列名称2 数据 ...
- 通过event事件来控制红绿灯通行车辆
事件的初始值为False,所以最开始就是红灯,先模拟红绿灯的规律,设定为每两秒变换一次灯,然后再模拟车辆通行,通过事件来将两者的事件结合起来, 当事件为False时,为红灯,车辆处于等待状态,一直wa ...
- Linux Linux下安装wine
Linux下安装wine Linux下安装wine可以从源码编译安装,但一般都觉得麻烦,所以尽量利用yum进行安装,解决很多包的依赖关系. 首先安装一个epel rpm -ivh http://dl. ...
- PHP+JQuery实现ajax跨域
jQuery实现ajax跨域 1.dataType:'jsonp'2.type: 'get'3.把要传的参数以url方式传出去 url:'http://gameapi.feiliu.com/lqzg ...