zoukankan      html  css  js  c++  java
  • 圆方树 学习笔记

    待填。。。现存代码

    仙人掌的圆方树

    模板题

    #include<bits/stdc++.h>
    #define rep(i,x,y) for(int i=x;i<=y;++i)
    #define per(i,x,y) for(int i=x;i>=y;--i)
    #define mar(o) for(int E=fst[o];E;E=e[E].nxt)
    #define marz(o) for(int E=fstz[o];E;E=ez[E].nxt)
    #define v e[E].to
    #define vz ez[E].to
    using namespace std;
    const int n7=20123,m7=40123;
    struct dino{int to,nxt,w;}e[m7],ez[m7];
    int n,m,T,dcnt,ecnt,t,fst[n7],fstz[n7];
    int dfn[n7],low[n7],fa[n7],dw[n7],cir[n7],s[n7];
    int dep[n7],fc[n7][21],snp,snq;
    
    int rd(){
    	int shu=0;char ch=getchar();
    	while(!isdigit(ch))ch=getchar();
    	while(isdigit(ch))shu=(shu<<1)+(shu<<3)+ch-'0',ch=getchar();
    	return shu;
    }
    
    void Dedge(int sta,int edn,int w,dino *eh,int *fsth){
    	ecnt++;
    	eh[ecnt]=(dino){edn,fsth[sta],w};
    	fsth[sta]=ecnt;
    }
    
    void edge(int sta,int edn,int w,dino *eh,int *fsth){
    	Dedge(sta,edn,w,eh,fsth),Dedge(edn,sta,w,eh,fsth);
    }
    
    void calc(int o1,int o2,int lasw){
    	int tot=lasw;
        for(int o=o2;o!=o1;o=fa[o]){
    		cir[o]=tot,tot+=dw[o];
    	}
    	dcnt++,cir[dcnt]=tot;
    	for(int o=o2;o!=o1;o=fa[o]){
    		edge(dcnt,o,min(cir[o],tot-cir[o]),ez,fstz);
    	}
    	edge(dcnt,o1,0,ez,fstz);
    } 
    
    void tarjan(int o){
    	t++,dfn[o]=low[o]=t;
    	mar(o){
    		if(v==fa[o])continue;
    		if(!dfn[v]){
    			fa[v]=o,dw[v]=e[E].w;
    			tarjan(v);
    			low[o]=min(low[o],low[v]);
    		}
    		low[o]=min(low[o],dfn[v]);
    		if(low[v]>dfn[o]){
    			edge(o,v,e[E].w,ez,fstz);  
    		}
    	}
    	mar(o){
    		if(fa[v]!=o&&dfn[v]>dfn[o])calc(o,v,e[E].w);
    	}
    }
    
    void dfs(int o){
    	rep(i,1,16)fc[o][i]=fc[ fc[o][i-1] ][i-1];
    	marz(o){
    		if(dep[vz])continue;
    		dep[vz]=dep[o]+1;
    		fc[vz][0]=o,s[vz]=s[o]+ez[E].w;
    		dfs(vz);
    	}
    }
    
    int Dlca(int p,int q){
    	if(dep[p]<dep[q])p^=q^=p^=q;
    	per(i,16,0){
    		if(dep[ fc[p][i] ]>=dep[q])p=fc[p][i];
    	}
    	if(p==q)return p;
    	per(i,16,0){
    		if(fc[p][i]!=fc[q][i])p=fc[p][i],q=fc[q][i];
    	}
    	snp=p,snq=q;
    	return fc[p][0];
    }
    
    int main(){
    	n=dcnt=rd(),m=rd(),T=rd();
    	rep(i,1,m){
    		int sta=rd(),edn=rd(),w=rd();
    		edge(sta,edn,w,e,fst);
    	}
    	ecnt=0;
    	tarjan(1);
    	dep[1]=1,dfs(1);
    	while(T--){
    		int p=rd(),q=rd();
    		int lca=Dlca(p,q),ans;
    		if(lca<=n)ans=s[p]+s[q]-2*s[lca];
    		else{
    			ans=s[p]-s[snp]+s[q]-s[snq];
    			if(cir[snp]<cir[snq])snp^=snq^=snp^=snq;
    			ans=ans+min(cir[snp]-cir[snq],cir[lca]-cir[snp]+cir[snq]);
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

    一般图的圆方树

    铁人两项

    #include<bits/stdc++.h>
    #define rep(i,x,y) for(int i=x;i<=y;++i)
    #define mar(o) for(int E=fst[o];E;E=e[E].nxt)
    #define marz(o) for(int E=fstz[o];E;E=ez[E].nxt)
    #define v e[E].to
    #define vz ez[E].to
    #define lon long long
    using namespace std;
    const int n7=101234,z7=201234,m7=401234;
    struct dino{int to,nxt;}e[m7],ez[m7];
    int n,m,dcnt,ecnt,fst[n7],fstz[z7],t,dfn[n7],low[n7],top,sak[n7];
    int val[z7],wei[z7],num,siz[z7];
    lon ans;bool in[n7];
    
    int rd(){
    	int shu=0;char ch=getchar();
    	while(!isdigit(ch))ch=getchar();
    	while(isdigit(ch))shu=(shu<<1)+(shu<<3)+ch-'0',ch=getchar();
    	return shu;
    }
    
    void edge(int sta,int edn,int *fsth,dino *eh){
    	ecnt++;
    	eh[ecnt]=(dino){edn,fsth[sta]};
    	fsth[sta]=ecnt;
    }
    
    void tarjan(int o){
    	num++;
    	t++,dfn[o]=low[o]=t;
    	top++,sak[top]=o,in[o]=1;
    	mar(o){
    		if(!dfn[v]){
    			tarjan(v);
    			low[o]=min(low[o],low[v]);
    			if(low[v]!=dfn[o])continue;
    			dcnt++;
    			while(sak[top+1]!=v){
    				edge(sak[top],dcnt,fstz,ez);
    				edge(dcnt,sak[top],fstz,ez);
    				val[ sak[top] ]=-1;
    				in[ sak[top] ]=0;
    				val[dcnt]++,top--;
    			}
    			val[dcnt]++,val[o]=-1;
    			edge(o,dcnt,fstz,ez);
    			edge(dcnt,o,fstz,ez);
    		}
    		else if(in[v])low[o]=min(low[o],dfn[v]);
    	}
    }
    
    void dfs(int o,int fa){
    	if(o<=n)siz[o]=1;
    	marz(o){
    		if(vz==fa)continue;
    		dfs(vz,o);
    		ans=ans+2ll*siz[o]*siz[vz]*val[o];
    		siz[o]+=siz[vz];
    	}
    	ans=ans+2ll*siz[o]*(num-siz[o])*val[o];
    }
    
    int main(){
    	n=dcnt=rd(),m=rd();
    	rep(i,1,m){
    		int sta=rd(),edn=rd();
    		edge(sta,edn,fst,e);
    		edge(edn,sta,fst,e);
    	}
    	ecnt=0;
    	rep(i,1,n){
    		if(dfn[i])continue;
    		num=0,tarjan(i),dfs(i,0);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    .net程序控制post数据 需登陆后保持session的方法
    简单分页查询SQL语句
    通过文本编辑器提交报从客户端中检测到有潜在危险的 Request.Form 值的错误
    Visual Studio 很卡、重置初始状态
    Jquery获取url中的参数
    Centos 6 安装桌面环境
    Jquery使用ajax实例
    一般处理程序使用session
    如何简单的发布一个react组件npm包
    BFC、IFC、GFC 和 FFC的概念
  • 原文地址:https://www.cnblogs.com/BlankAo/p/14232714.html
Copyright © 2011-2022 走看看