【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
题目描述
“我有个愿望,我希望在灿烂千阳时遇见你。”
这是个有n个点的世界,有m条无向边连接着这n个点,但是不保证点之间能够互相到达。
“这个世界的夕阳,只在奇数长的简单路径的尽头。”一个神如是说。
于是我想知道对于一个点对(x,y),x到y之间的所有简单路径中是否存在长度为奇数的路径,只有这样,我才能找到存在有夕阳的路。
数据范围
对于50%的数据,1≤n,m,q≤500
对于100%的数据,,1≤n,q,m≤100000
保证没有自环与重边。
解法
首先判断每条边是否是存在于一个奇数长度的简单环中,标记为奇边。①
然后对原图生成树, 对于询问(x,y),回答“Yes”当且仅当:
x,y隶属于同一棵树中,并且满足以下条件其中之一:
1.x,y在树上路径的距离为奇数;
2.x,y在树上路径上有一条边被标记为奇边。②
①实现:
对原图进行tarjan点双连通分量,对于一条虚边(x,y),如果x,y在tarjan树上的距离为偶数,那么加上这条边的话,x,y一定在一个包含(x,y)的奇环中,所以(x,y)就是一条奇边。
tarjan树:由tarjan的遍历呈树形,这棵树姑且称为tarjan树。
虚边:x,y存在一条边,且x比y更晚入栈,这样的边姑且称为虚边。
如果(x,y)是一条奇边,那么包含这条边的点双连通分量的所有边都是奇边。
简单证明:任取点双连通分量里面的一条边(x,y),如果树上路径(x,y)不是奇边,那么一定可以反向走找到一条包含奇边的路径。
②实现:
LCA求树上和。
代码
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
#define ln(x,y) int(log(x)/log(y))
using namespace std;
const char* fin="sunset.in";
const char* fout="sunset.out";
const int inf=0x7fffffff;
const int maxn=100007,maxm=maxn*2,maxk=20;
int n,m,i,j,k,t;
int fi[maxn],la[maxm],ne[maxm],tot;
int color,co[maxn];
int stack[maxn],low[maxn],dfn[maxn],num;
int de[maxn],dad[maxn],bitch[maxn];
int fa[maxn][maxk],va[maxn][maxk];
bool bz[maxn],az[maxn],cz[maxm];
int c[maxn];
bool re[maxn];
int getdad(int x){
if (dad[x]==x) return x;
dad[x]=getdad(dad[x]);
return dad[x];
}
void add_line(int x,int y){
tot++;
ne[tot]=fi[x];
la[tot]=y;
fi[x]=tot;
}
void tarjan(int v,int from){
int i,j,k;
co[v]=color;
dfn[v]=low[v]=++num;
de[v]=de[from]+1;
//bz[stack[j=++stack[0]]=v]=true;
for (k=fi[v];k;k=ne[k])
if (!cz[(k+1)/2]){
j=stack[0];
stack[++stack[0]]=(k+1)/2;
cz[(k+1)/2]=true;
if (!dfn[la[k]]){
fa[la[k]][0]=v;
tarjan(la[k],v);
low[v]=min(low[v],low[la[k]]);
if (low[la[k]]>=dfn[v]){
bool haveji=false;
c[0]=0;
while (stack[0]>j){
i=stack[stack[0]];
haveji|=az[i];
if (!re[la[i*2]]) c[++c[0]]=la[i*2],re[la[i*2]]=true;
if (!re[la[i*2-1]]) c[++c[0]]=la[i*2-1],re[la[i*2-1]]=true;
stack[0]--;
}
for (i=1;i<=c[0];i++) {
if (haveji && re[fa[c[i]][0]]) va[c[i]][0]=1;
}
for (i=1;i<=c[0];i++) re[c[i]]=false;
}
}else{
low[v]=min(low[v],low[la[k]]);
if (de[la[k]]%2==de[v]%2) az[(k+1)/2]=true;
}
}
}
void up(int &a,int i,int &k){
k+=va[a][i];
a=fa[a][i];
}
int lca(int a,int b){
int i,j,k=0;
if (de[a]<de[b]) swap(a,b);
for (i=ln(de[a]-de[b],2);i>=0;i--) if (de[fa[a][i]]>de[b]) up(a,i,k);
if (de[a]!=de[b]) up(a,0,k);
for (i=ln(de[a],2);i>=0;i--) if (fa[a][i]!=fa[b][i]) up(a,i,k),up(b,i,k);
if (a!=b) up(a,0,k),up(b,0,k);
return k;
}
int main(){
freopen(fin,"r",stdin);
freopen(fout,"w",stdout);
scanf("%d%d",&n,&m);
for (i=1;i<=m;i++){
scanf("%d%d",&j,&k);
add_line(j,k);
add_line(k,j);
}
for (i=1;i<=n;i++) if (!dfn[i]) color++,tarjan(i,0);
//for (i=1;i<=n;i++) if (az[dad[i]]) va[i][0]=1;
for (i=1,j=ln(n,2);i<=j;i++)
for (k=1;k<=n;k++){
fa[k][i]=fa[fa[k][i-1]][i-1];
va[k][i]=va[fa[k][i-1]][i-1]+va[k][i-1];
}
scanf("%d",&t);
for (;t;t--){
scanf("%d%d",&j,&k);
if (co[j]==co[k] && (de[j]%2!=de[k]%2 || lca(j,k))) printf("Yes\n");
else printf("No\n");
}
return 0;
}
启发
点双连通分量
在一棵生成树上,如果一个点x,不存在一个son[x]有虚边连向x的祖先,那么x就是一个割点;
依靠割点找出点双连通分量。
路径询问问题
先对原图进行生成树,再考虑会不会简单一些呢?
(留坑待填)
【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳的更多相关文章
- JZOJ 【NOIP2016提高A组集训第16场11.15】兔子
JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...
- 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集
题目描述 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 数据范围 40%的数据满足: ...
- 【NOIP2016提高A组集训第14场11.12】随机游走
题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...
- 【NOIP2016提高A组集训第13场11.11】最大匹配
题目 mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边. 图的"匹配"是指这个图的一个边集,里面的边两两不存在公 ...
- 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP
好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...
- 【JZOJ4901】【NOIP2016提高A组集训第18场11.17】矩阵
题目描述 他是一名普通的农电工,他以一颗无私奉献的爱岗敬业之心,刻苦钻研业务,以娴熟的技术.热情周到的服务赢得了广大客户的尊敬和赞美.他就是老百姓称为"李电"的李春来. 众所周知, ...
- 【JZOJ4898】【NOIP2016提高A组集训第17场11.16】人生的价值
题目描述 NiroBC终于找到了人生的意义,可是她已经老了,在新世界,没有人认识她,她孤独地在病榻上回顾着自己平凡的一生,老泪纵横.NiroBC多么渴望再多活一会儿啊! 突然一个戴着黑色方框眼镜,方脸 ...
随机推荐
- springboot 2 Hikari 多数据源配置问题(dataSourceClassName or jdbcUrl is required)
springboot 2 Hikari 多数据源配置问题(dataSourceClassName or jdbcUrl is required) 最近在项目中想试一下使用 Hikari 连接池,以前用 ...
- 在线模拟http-post请求
今天,要测试一个post请求的API,找了下,下面的网站可以直接利用起来,mark下 http://www.atool.org/httptest.php
- js之简单工厂模式
简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...
- TCP/TP:DNS区域(Zone)
之前阅读资料不是特别明白,看到一个博主的解释,豁然开朗,特此记录. https://blog.csdn.net/huangzx3/article/details/79347556 DNS区域(ZONE ...
- poj 2398 Toy Storage(计算几何 点线关系)
Toy Storage Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4588 Accepted: 2718 Descr ...
- WebBrowser修改默认白色背景
背景:在使用Winform的WebBrowser显示网页的时候,在网页还未加载完成之前会显示白色,刚好网页内容呈现黑色,这样视觉效果上就十分差,想把这层白色的去掉. 试了很久之后发现根本去不掉,应 ...
- BZOJ2529: [Poi2011]Sticks
2529: [Poi2011]Sticks Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 257 Solved: ...
- ubuntu安装搜狗输入法后无法使用goland的快捷键 ctrl+alt+B
安装了搜狗拼音后,其快捷键ctrl+alt+b会启动软键盘,造成与其他编辑器快捷键的冲突. 为了禁止使用ctrl+alt+b启动软键盘,可以: 1. 在搜狗拼音输入法选择设置 2. 高级设置 3. 高 ...
- 阿里毕玄:来测试下你的Java编程能力
上篇整理了下后面准备更系统化写的Java编程进阶的思路,如果仅看里面的词,很多同学会觉得都懂,但我真心觉得没有多少人是真懂的,所以简单的想了一些题目,感兴趣的同学们可以来做做看,看看自己的Java编程 ...
- ML面试1000题系列(81-90)
本文总结ML面试常见的问题集 转载来源:https://blog.csdn.net/v_july_v/article/details/78121924 81.已知一组数据的协方差矩阵P,下面关于主分量 ...