• #圆方树,树链剖分#P4334 [COI2007] Policija


    题目


    分析

    先建一棵圆方树,必经点(z)就是满足(z)(x)(y)之间的路径上,
    这个直接用树链剖分做,必经边必须要满足不在环上,
    那么这个必经边就可以找到一个方点,就可以转换成必经点的问题


    代码

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #define rr register
    using namespace std;
    const int N=200011; struct node{int y,next;}e[N*5],E[N*5]; map<pair<int,int>,int>uk;
    int dfn[N],low[N],stac[N],hs[N],dep[N],nfd[N],fat[N],big[N],et=1,Et=1;
    int as[N],siz[N],Top[N],cnt[N],dis[N],tot,TOP,n,ext,m,las,a[N],Q;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline void add(int x,int y){
    	e[++et]=(node){y,as[x]},as[x]=et;
    	e[++et]=(node){x,as[y]},as[y]=et;
    }
    inline signed min(int a,int b){return a<b?a:b;}
    inline void tarjan(int x,int F){
    	dfn[x]=low[x]=++tot,stac[++TOP]=x;
    	for (rr int i=hs[x];i;i=E[i].next)
    	if (!dfn[E[i].y]){
    		tarjan(E[i].y,i^1);
    		low[x]=min(low[x],low[E[i].y]);
    		if (dfn[x]<=low[E[i].y]){
    			cnt[++ext]=2;
    			if (dfn[x]<low[E[i].y]){
    				rr int X=x,Y=E[i].y;
    				if (X>Y) X^=Y,Y^=X,X^=Y;
    				uk[make_pair(X,Y)]=ext; 
    			}
    			for (;stac[TOP]!=E[i].y;--TOP)
    			    add(ext,stac[TOP]),++cnt[ext];
    			add(ext,stac[TOP--]),add(ext,x);
    		}
    	}else if (i!=F) low[x]=min(low[x],dfn[E[i].y]);
    }
    inline void dfs1(int x,int fa){
    	dep[x]=dep[fa]+1,fat[x]=fa,
    	dis[x]=dis[fa]+(x<=n),siz[x]=1;
    	for (rr int i=as[x],SIZ=-1;i;i=e[i].next)
    	if (e[i].y!=fa){
    		dfs1(e[i].y,x),siz[x]+=siz[e[i].y];
    		if (siz[e[i].y]>SIZ) big[x]=e[i].y,SIZ=siz[e[i].y];
    	}
    }
    inline void dfs2(int x,int linp){
    	dfn[x]=++tot,nfd[tot]=x,Top[x]=linp;
    	if (!big[x]) return; dfs2(big[x],linp);
    	for (rr int i=as[x];i;i=e[i].next)
    	if (e[i].y!=fat[x]&&e[i].y!=big[x])
    	    dfs2(e[i].y,e[i].y);
    }
    inline bool pass_by(int x,int y,int z){
    	for (;Top[x]!=Top[y];x=fat[Top[x]]){
    		if (dep[Top[x]]<dep[Top[y]]) x^=y,y^=x,x^=y;
    		if (Top[z]==Top[x]&&dep[z]<=dep[x]) return 1;
    	}
    	if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
    	if (Top[y]==Top[z]&&dep[x]<=dep[z]&&dep[z]<=dep[y]) return 1;
    	return 0;
    }
    signed main(){
    	ext=n=iut(),m=iut();
    	for (rr int i=1;i<=m;++i){
    		rr int x=iut(),y=iut();
    		E[++Et]=(node){y,hs[x]},hs[x]=Et,
    		E[++Et]=(node){x,hs[y]},hs[y]=Et;
    	}
    	tarjan(1,0),tot=TOP=0,dfs1(1,0),dfs2(1,1);
    	for (rr int Q=iut();Q;--Q){
    		rr int opt=iut(),x=iut(),y=iut(),z;
    		if (opt==1){
    			rr int X=iut(),Y=iut();
    			if (X>Y) X^=Y,Y^=X,X^=Y;
    			z=uk[make_pair(X,Y)];
    			if (!z) {puts("yes"); continue;}
    		}else z=iut();
    		puts(pass_by(x,y,z)?"no":"yes");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Nginx 部署多个 web 项目(虚拟主机)
    Nginx 配置文件
    Linux 安装 nginx
    Linux 安装 tomcat
    Linux 安装 Mysql 5.7.23
    Linux 安装 jdk8
    Linux 安装 lrzsz,使用 rz、sz 上传下载文件
    springMVC 拦截器
    spring 事务
    基于Aspectj 注解实现 spring AOP
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14980367.html
Copyright © 2020-2023  润新知