树剖56pts求助
查看原帖
树剖56pts求助
700106
Xdik楼主2023/12/2 17:27

rt,思路是树剖+st表维护路径上最大和次大值,将边权下放到点权的

#include<bits/stdc++.h>
#define int long long
#pragma GCC optimeze(2)
#pragma GCC optimeze(3)
using namespace std;
const int N=1e5+5;
long long read(){
	long x=0,flag=1;
	char ch=0;
	while(ch<'0'||ch>'9'){
		if(ch=='-')flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+ch-48;
		ch=getchar();
	}
	return x*flag;
}
int n,m,ff[N],ver[N*2],ne[N*2],head[N],tot=0,v[N*2],de[N],dfn[N],top[N],fa[N],rk[N],cnt=0,g1[N][25],g2[N][25],q[N],size[N],son[N];
bool vis[N];
struct edge{
	int u,v,w;
}a[3*N];
bool cmp(edge a,edge b){
	return a.w<b.w;
}
int find(int x){
	if(x==ff[x])return x;
	return ff[x]=find(ff[x]);
}
void merge(int x,int y){
	x=find(x),y=find(y);
	if(x!=y){
		ff[x]=y;
	}
}
void add(int x, int y, int k){ver[++tot]=y,ne[tot]=head[x],head[x]=tot,v[tot]=k;}
void dfs1(int t,int f,int dep){
	de[t]=dep;
	fa[t]=f;
	size[t]=1;
	for(int i=head[t];i;i=ne[i]){
		int to=ver[i];
		if(to==f)continue;
		q[to]=v[i];
		dfs1(to,t,dep+1);
		size[t]+=size[to];
		if(size[to]>size[son[t]])son[t]=to;
	}
}
void dfs2(int t,int op){
	top[t]=op;
	dfn[t]=++cnt;
	rk[cnt]=t;
	if(son[t])dfs2(son[t],op);
	for(int i=head[t];i;i=ne[i]){
		int to=ver[i];
		if(to==fa[t]||to==son[t])continue;
		dfs2(to,to);
	}
}
pair<int,int> mg(int x,int y,int z,int k){
	pair<int,int>ans;
	int a[5]={};
	a[1]=x;
	a[2]=y;
	a[3]=z;
	a[4]=k;
	sort(a+1,a+5);
	int n=unique(a+1,a+5)-a-1;
	ans.second=a[n];
	ans.first=a[n-1];
	if(n==1)ans.first=-11451419198109;
	return ans;
}
void st(){
	int gm=log(n)/log(2);
	memset(g2,0xc0,sizeof g2);
	memset(g1,0xc0,sizeof g1);
	for(int i=2;i<=n;i++){
		g1[i][0]=q[rk[i]];
	}
	for(int j=1;j<=gm;j++){
		for(int i=2;i+(1<<(j-1))<=n;i++){
			pair<int,int>s=mg(g1[i][j-1],g2[i][j-1],g1[i+(1<<(j-1))][j-1],g2[i+(1<<(j-1))][j-1]);
			g1[i][j]=s.second;
			g2[i][j]=s.first;
		}
	}
}
pair<int,int> qu(int l,int r){
	int k=log(r-l+1)/log(2);
	return mg(g1[l][k],g2[l][k],g1[r-(1<<k)+1][k],g2[r-(1<<k)+1][k]);
} 
pair<int,int>getans(int x,int y){
	int fx=top[x],fy=top[y];
	pair<int,int>ans;
	ans.first=-11451419198109;
	ans.second=-11451419198109;
	while(fx!=fy){
		if(de[fx]<de[fy])swap(fx,fy),swap(x,y);
		pair<int,int>hb=qu(dfn[fx],dfn[x]);
		ans=mg(ans.first,ans.second,hb.first,hb.second);
		x=fa[top[x]],fx=top[x];
	}
	if(de[x]<de[y])swap(x,y);
	pair<int,int>hb=qu(dfn[x],dfn[y]);
	ans=mg(ans.first,ans.second,hb.first,hb.second);
	return ans;
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++)ff[i]=i;
	for(int i=1;i<=m;i++){
		a[i].u=read(),a[i].v=read(),a[i].w=read();
	}
	sort(a+1,a+1+m,cmp);
	int xykakioi=0,sum=0;
	for(int i=1;i<=m;i++){
		int x=find(a[i].u),y=find(a[i].v);
		if(x!=y){
			sum+=a[i].w;
			add(a[i].u,a[i].v,a[i].w);
			add(a[i].v,a[i].u,a[i].w);
			vis[i]=1;
			merge(x,y);
			xykakioi++;
		}
		if(xykakioi==n-1)break;
	}
	dfs1(1,0,0);
	dfs2(1,1);
	st();
	int minn=INT_MAX;
	for(int i=1;i<=m;i++){
		if(vis[i]||a[i].u==a[i].v)continue;
		pair<int,int>ans=getans(a[i].u,a[i].v); 
		int bj;
		if(ans.second==a[i].w)bj=a[i].w-ans.first;
		else bj=a[i].w-ans.second;
		minn=min(minn,bj);
	}
	cout<<sum+minn;
	return 0;
}
2023/12/2 17:27
加载中...