【NOIP2016提高A组集训第5场11.2】夕阳
2016-11-02 20:36
281 查看
Description
“我有个愿望,我希望在灿烂千阳时遇见你。”这是个有n个点的世界,有m条无向边连接着这n个点,但是不保证点之间能够互相到达。
“这个世界的夕阳,只在奇数长的简单路径的尽头。”一个神如是说。
于是我想知道对于一个点对(x,y),x到y之间的所有简单路径中是否存在长度为奇数的路径,只有这样,我才能找到存在有夕阳的路。
Solution
如果两个点存在奇数的路径,那么这两个点存在于用一个奇环中。问题就是怎么找奇环。
tarjan算法。
那么求边双连通分量,构出的tarjan树,当存在一条虚边的时候(就是连出去的那个点已经在栈中出现过了),那么这个虚边构成的简单环中的边都是奇环,退栈的时候暴力修改就好了。
最后询问两个点的lca,如果他们的深度差是奇数或者路径中有奇环上的边的话,那么就合法。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) #define rep(i,a) for(i=first[a];i;i=next[i]) using namespace std; const int maxn=100007; int i,j,k,l,t,n,m,ans,x,y,z,cas,u,v,zhi; int first[maxn*2],last[maxn*2],next[maxn*2],num; int f[maxn][20],g[maxn][20]; int dfn[maxn],low[maxn],stack[maxn],dfx,h[maxn],hhh,deep[maxn]; bool az[maxn],cz[maxn],bz[maxn]; void add(int x,int y){ last[++num]=y,next[num]=first[x],first[x]=num; } int tarjan(int x){ int i; stack[++stack[0]]=x; dfn[x]=low[x]=++dfx; az[x]=1; rep(i,x){ if((!cz[(i-1)^1])&&(!cz[i-1])){ cz[i-1]=1; if(!dfn[last[i]]){ deep[last[i]]=deep[x]+1; f[last[i]][0]=x; tarjan(last[i]); low[x]=min(low[x],low[last[i]]); } else if(az[last[i]]){ if(deep[last[i]]%2==deep[x]%2){ /* g[last[i]][0]--; g[x][0]++;*/ g[x][0]++; } low[x]=min(low[x],dfn[last[i]]); } } } if(dfn[x]==low[x]){ int p=0,u=stack[0]; hhh++; while(stack[stack[0]+1]!=x){ p=max(g[stack[stack[0]]][0],p); h[stack[stack[0]]]=hhh; az[stack[stack[0]]]=0; stack[0]--; } if(p)fo(i,stack[0]+1,u)g[stack[i]][0]++; } } int lca(int x,int y){ zhi=0; int i;if(deep[x]<deep[y])swap(x,y); fod(i,19,0)if(deep[f[x][i]]>deep[y])zhi+=g[x][i],x=f[x][i]; if(deep[x]!=deep[y])zhi+=g[x][0],x=f[x][0]; fod(i,19,0)if(f[x][i]!=f[y][i])zhi+=g[x][i]+g[y][i],x=f[x][i],y=f[y][i]; if(x!=y){zhi+=g[x][0]+g[y][0];return f[x][0];}return x; } int main(){ // freopen("sunset.in","r",stdin); // freopen("sunset.out","w",stdout); freopen("fan.in","r",stdin); // freopen("fan.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,m){ scanf("%d%d",&x,&y); add(x,y),add(y,x); } fo(i,1,n){ if(!dfn[i])tarjan(i); } fo(j,1,19){ fo(i,1,n)f[i][j]=f[f[i][j-1]][j-1],g[i][j]=g[f[i][j-1]][j-1]+g[i][j-1]; } for(scanf("%d",&cas);cas;cas--){ scanf("%d%d",&x,&y); int o=lca(x,y); if(!o){printf("No\n");continue;} if(((deep[x]+deep[y]-2*deep[o])%2==1)||zhi){ printf("Yes\n"); } else printf("No\n"); } }
相关文章推荐
- 【JZOJ4847】【NOIP2016提高A组集训第5场11.2】夕阳
- JZOJ4847【NOIP2016提高A组集训第5场11.2】夕阳
- 4847. 【NOIP2016提高A组集训第5场11.2】夕阳
- 【JZOJ4845】【NOIP2016提高A组集训第5场11.2】寻找
- 【NOIP2016提高A组集训第5场11.2】寻找
- 【JZOJ4846】【NOIP2016提高A组集训第5场11.2】行走
- 【NOIP2016提高A组集训第5场11.2】行走
- JZOJ 4845 【NOIP2016提高A组集训第5场11.2】寻找
- JZOJ4846【NOIP2016提高A组集训第5场11.2】行走
- 4845. 【NOIP2016提高A组集训第5场11.2】寻找
- 【NOIP2016提高A组集训第1场10.29】小W学物理
- {题解}[jzoj4823] 【NOIP2016提高A组集训第1场10.29】小W学物理
- 小W学物理【NOIP2016提高A组集训第1场10.29】
- 【NOIP2016提高A组集训第3场10.31】高维宇宙
- JZOJ4877. 【NOIP2016提高A组集训第10场11.8】力场护盾
- 【JZOJ4878】【NOIP2016提高A组集训第10场11.8】时空传送
- JZOJ 4879 【NOIP2016提高A组集训第11场11.9】少女觉
- NOIP2016提高A组集训第16场11.15 总结
- 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰
- 【JZOJ4901】【NOIP2016提高A组集训第18场11.17】矩阵