题目描述

“我有个愿望,我希望在灿烂千阳时遇见你。”
这是个有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就是一个割点;
依靠割点找出点双连通分量。

路径询问问题

先对原图进行生成树,再考虑会不会简单一些呢?
(留坑待填)

转载于:https://www.cnblogs.com/hiweibolu/p/6714854.html

【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳相关推荐

  1. 【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块

    题目描述 Dpstr最近迷上了推冰块.冰地是一个n行m列的网格区域,第i行第j列的格子记为(i,j),也就是左上角为(1,1),右下角为(n,m).每个格子可能是冰面.障碍物.减速带三者之一.其中,冰 ...

  2. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取 ...

  3. JZOJ4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰 2017.10(B组)

    Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取 ...

  4. 【JZOJ4884】【NOIP2016提高A组集训第12场11.10】图的半径

    题目描述 mhy12345学习了树的直径,于是开始研究图的半径,具体来说,我们需要在图中选定一个地方作为中心,其中这个中心有可能在路径上. 而这个中心的选址需要能够使得所有节点达到这个中心的最短路里面 ...

  5. JZOJ4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    题目 20 40 80 100 大致流程 code 题目 Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核 ...

  6. jzoj 4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    Description 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取 ...

  7. 【JZOJ4883】【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰

    题目描述 在炽热的核熔炉中,居住着一位少女,名为灵乌路空. 据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量--核能. 核焰,可融真金. 咳咳. 每次核融的时候,空都会选取一些原子,排成 ...

  8. 【JZOJ4896】【NOIP2016提高A组集训第16场11.15】兔子

    题目描述 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子窝之 ...

  9. JZOJ4870. 【NOIP2016提高A组集训第9场11.7】涂色游戏

    Description Data Constraint Solution 我们设f[i][j]表示当前有i个格子恰好放了j种颜色的方案数,那么f[i][j]=f[i−1][j−1]∗(p−(j−1)) ...

  10. 【NOIP2016提高A组集训第7场11.4】推冰块

    Description Dpstr最近迷上了推冰块.冰地是一个n行m列的网格区域,第i行第j列的格子记为(i,j),也就是左上角为(1,1),右下角为(n,m).每个格子可能是冰面.障碍物.减速带三者 ...

最新文章

  1. 开启灯光就是近光吗_保时捷Macan大灯改装技术,东莞专业豪车灯光改装修复。保时捷改LED大灯...
  2. jQuery选择器介绍:基本选择器、层次选择器、过滤选择器、表单选择器
  3. 数据库-索引-普通索引-唯一索引
  4. POJ 1007 DNA Sorting
  5. LeetCode 94. 二叉树的中序遍历(中序遍历)
  6. Tomcat核心架构和启动流程解析
  7. Linux系统调用表:x86和x86_64
  8. 树莓派无法安装mariadb_RaspberryPi(树莓派)安装 MariaDB 数据库没有办法远程访问...
  9. 适合初学者的sql_适用于初学者SQL多重连接示例
  10. 打印出来只有a4纸一半 预览是正常的_还需要去打印店?能随身使用的便携打印机:汉印MT800评测...
  11. php获取所有url地址_PHP_php 获取完整url地址,主要是获取到地址栏的一些信 - phpStudy...
  12. php滑到底部自动加载更多,ListView滑动到底部自动加载更多
  13. WINDOWS2016故障转移群集
  14. 仿Tumblr点赞心破碎动画
  15. 中文字体压缩器并且转换(推荐阅读)
  16. 驱动开发之注册表:获取注册表HKEY_CURRENT_USER对应路径(SID)
  17. 转:领导者能够坦诚错误,员工就能畅所欲言
  18. [高数][高昆轮][高等数学上][第一章-函数与极限]02.数列的极限
  19. 基于51单片机简易智能家居
  20. 蓝桥杯单片机第11届国赛程序题参考答案

热门文章

  1. 过河孙小弟scratch
  2. oracle job remove,如何删除oracle Job命令实例
  3. 64位Win10 2004正式版_MSDN我告诉你win10 2004镜像下载
  4. 韩信点兵问题的简单算法 downmoon
  5. 【Unity开发小技巧】Unity混音器Mixer控制全局音量
  6. 20181216——自定义全局指令
  7. wordpress登录美化css,wordpress的XIU主题显示美化css配置
  8. 2019.9.15训练总结
  9. linux memery dump
  10. CDN有什么加速方式