MnZn刚学OI,求助圆方树模板输出0
查看原帖
MnZn刚学OI,求助圆方树模板输出0
285617
黑影洞人楼主2022/9/13 13:26
#include<cstdio>
#include<algorithm>
#define N 1919810 
using namespace std;
int vl[N],val[N],he[N],ver[N],ne[N],tot,cnt,head[N],to[N],nxt[N];
int f[N][20],dep[N],d[N],s[N],sc[N];
int fw[N],fi[N],fa[N],dia;
int dfn[N],low[N],idx;
int n,m,q,e,g;
void add(int u,int v,int w){
	//printf("%d %d\n",u,v);
	to[++tot]=u;
	nxt[tot]=head[v];
	head[v]=tot;
	val[tot]=w;
}
void add2(int u,int v,int w){
	ver[++cnt]=v;
	ne[cnt]=he[u];
	he[u]=cnt;
	vl[cnt]=w;
}
void build(int u,int v,int w){
	int sum=w;
	for(int i=v;i!=u;i=fa[i]){
		s[i]=sum;
		sum+=fw[i]; 
	}
	s[u]=sc[u]=sum;
	add2(u,++dia,0);
	for(int i=v;i!=u;i=fa[i]){
		sc[i]=sum;
		add(dia,i,min(s[i],min(sum-s[i],s[i])));
	}
}
void tarjan(int x,int fat){
	dfn[x]=low[x]=++idx;
	for(int i=he[x];i;i=ne[i]){
		int y=ver[i],w=vl[i];
		if(y==fat)continue;
		if(!dfn[y]){
			fa[y]=x,fw[y]=w,fi[y]=i;
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
		}else low[x]=min(low[x],dfn[y]);
		if(dfn[x]<low[y])add(x,y,w);
	}
	for(int i=he[x];i;i=ne[i]){
		int y=ver[i],w=vl[i];
		if(fi[y]!=i&&dfn[x]<dfn[y])build(x,y,w);
	}
}
void dfs(int x,int fa){
	dep[x]=dep[fa]+1;
	f[x][0]=fa;
	for(int i=1;i<=19;i++)f[x][i]=f[f[x][i-1]][i-1];
	for(int i=head[x];i;i=nxt[i]){
		int y=to[i],w=val[i];
		if(y==fa)continue;
		d[y]=d[x]+w;
		//puts("1");
		dfs(y,x);
	}
}
int lca(int x,int y){
	if(dep[x]<dep[y])swap(x,y);
	for(int i=19;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
	if(x==y)return x;
	for(int i=19;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
	e=x,g=y;
	return f[x][0];
}
signed main(){
	scanf("%d%d%d",&n,&m,&q);
	dia=n;
	for(int i=1;i<=m;i++){
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		add2(a,b,c);
		add2(b,a,c);
	}
	tarjan(1,0);
	dfs(1,0);
	while(q--){
		int a,b,c;
		scanf("%d%d",&a,&b);
		//printf("%d %d\n",d[a],d[b]);
		c=lca(a,b);
		if(c<=n){
			printf("%d\n",d[a]+d[b]-2*d[c]);
		}else{
			int w=abs(s[e]-s[g]);
			printf("%d\n",d[a]-d[e]+d[b]-d[g]+min(w,sc[g]-w));
		}
	}
	return 0;
}



2022/9/13 13:26
加载中...