树剖90pts
查看原帖
树剖90pts
252549
Iwara楼主2023/11/4 14:16

RT

#include<bits/stdc++.h>
#include<map> 
using namespace std;
typedef long long ll;
#define int long long
const ll MAXN=1e5+5,MAXM=2e6+5,INF=0x7f7f7f7f7f;
ll n,m;
struct edge{
	ll u,v,w,nxt;
	bool op;
	bool operator < (const edge &oth)const{
		return w<oth.w;
	}
	bool operator == (const edge &oth)const{
		return (u==oth.u&&v==oth.v&&w==oth.w);
	}
};
edge e[MAXM],tree[MAXM];
ll head_e[MAXN],head_tree[MAXN],e_num,tree_num;
void add_e(ll From,ll To,ll Len){
	e_num++;
	e[e_num].u=From;
	e[e_num].v=To;
	e[e_num].w=Len;
	e[e_num].nxt=head_e[From];
	e[e_num].op=0;
	head_e[From]=e_num;
	return; 
} 
void add_tree(ll From,ll To,ll Len){
	tree_num++;
	tree[tree_num].u=From;
	tree[tree_num].v=To;
	tree[tree_num].w=Len;
	tree[tree_num].nxt=head_tree[From];
	head_tree[From]=tree_num;
	return; 
} 
ll x,y,z;
ll dsu[MAXN];
ll Find(ll qwq){
	return dsu[qwq]==qwq?qwq:dsu[qwq]=Find(dsu[qwq]);
}
ll sum_l;
void kruskal(){
	stable_sort(e+1,e+1+e_num);
	for(int i=1;i<=n;i++)dsu[i]=i;
	ll tmp=0;
	for(int i=1;i<=e_num&&tmp<n-1;i++){
		ll f_u=Find(e[i].u),f_v=Find(e[i].v);
		if(f_u==f_v)continue;
		dsu[f_u]=f_v;
		add_tree(e[i].u,e[i].v,e[i].w);
		add_tree(e[i].v,e[i].u,e[i].w);
		if(i&1)e[i].op=e[i+1].op=1;
		else e[i].op=e[i-1].op=1;
		sum_l+=e[i].w;
		tmp++;
	}
	return;
}
pair<ll,ll> mix(pair<ll,ll> p1,pair<ll,ll> p2){
	if(p1.first==-1)return p2;
	if(p2.first==-1)return p1;
	if(p1.first>p2.first)return make_pair(p1.first,max(p1.second,p2.first));
	else if(p1.first<p2.first)return make_pair(p2.first,max(p2.second,p1.first));
	else return make_pair(p1.first,max(p1.second,p2.second));
}
struct sgm_t{
	ll num1[MAXN<<3],num2[MAXN<<3];
	void clear(){
		fill(num1,num1+(MAXN<<2)+10,-1);
		fill(num2,num2+(MAXN<<2)+10,-1);
		return;
	}
	void push_up(ll id){
		pair<ll,ll> pl=make_pair(num1[id<<1],num2[id<<1]),pr=make_pair(num1[id<<1|1],num2[id<<1|1]);
		pair<ll,ll> QwQ=mix(pl,pr);
		num1[id]=QwQ.first;
		num2[id]=QwQ.second;
		return;
	}
	void update(ll id,ll L,ll R,ll k,ll delta){
		if(L>R||k<L||k>R)return;
		if(L==R){
			if(num1[id]==-1)num1[id]=delta;
			else{
				if(delta>num1[id])num2[id]=num1[id],num1[id]=delta;
				else if(delta<num1[id]&&delta>num2[id])num2[id]=delta;
			}
			return;
		}
		ll mid=(L+R)>>1;
		update(id<<1,L,mid,k,delta);
		update(id<<1|1,mid+1,R,k,delta);
		push_up(id);
		return;
	}
	pair<ll,ll> query(ll id,ll L,ll R,ll QL,ll QR){
//		if(num2[id]==0)cout<<"ERROR!"<<endl;
		if(R<QL||L>QR)return make_pair(-1,-1);
		if(QL<=L&&R<=QR)return make_pair(num1[id],num2[id]);
		ll mid=(L+R)>>1;
		return mix(query(id<<1,L,mid,QL,QR),query(id<<1|1,mid+1,R,QL,QR));
	}
}S;
ll fa[MAXN],deep[MAXN],sz[MAXN],hson[MAXN];
ll Len[MAXN];
void pre(ll now){
	sz[now]=1;
	for(int i=head_tree[now];i;i=tree[i].nxt){
		if(tree[i].v==fa[now])continue;
		fa[tree[i].v]=now;
		deep[tree[i].v]=deep[now]+1;
		Len[tree[i].v]=tree[i].w;
		pre(tree[i].v);
		sz[now]+=sz[tree[i].v];
		if(sz[tree[i].v]>sz[hson[now]])hson[now]=tree[i].v;
	}
	return;
}
ll dfn[MAXN],rk[MAXN],cnt,top[MAXN];
void cut(ll now,ll rt){
	dfn[now]=++cnt;
	rk[cnt]=now;
	top[now]=rt;
	S.update(1,1,n,cnt,Len[now]);
	if(hson[now])cut(hson[now],rt);
	for(int i=head_tree[now];i;i=tree[i].nxt){
		if(tree[i].v==fa[now]||tree[i].v==hson[now])continue;
		cut(tree[i].v,tree[i].v);
	}
	return;
} 
pair<ll,ll> max_l(ll X,ll Y){
//	cout<<"case: "<<X<<" "<<Y<<endl;
	pair<ll,ll> ans=make_pair(-1,-1); 
	if(deep[top[X]]<=deep[top[Y]])swap(X,Y);
	while(deep[top[X]]>deep[top[Y]])ans=mix(ans,S.query(1,1,n,dfn[top[X]],dfn[X])),X=fa[top[X]];
//	if(ans.second==0)cout<<"now!"<<endl;
	if(X==Y)return ans;
	while(top[X]!=top[Y]){
		if(deep[top[X]]>deep[top[Y]])ans=mix(ans,S.query(1,1,n,dfn[top[X]],dfn[X])),X=fa[top[X]];
		else ans=mix(ans,S.query(1,1,n,dfn[top[Y]],dfn[Y])),Y=fa[top[Y]];
	}
	if(dfn[X]>dfn[Y])swap(X,Y);
//	if(ans.second==0)cout<<"now!!!"<<endl;
//	cout<<S.query(1,1,n,dfn[X]+1,dfn[Y]).second<<endl;
	ans=mix(ans,S.query(1,1,n,dfn[X]+1,dfn[Y]));
//	if(ans.second==0)cout<<"now!"<<endl;
	return ans;
}
ll reg;
ll Ans=INF;
signed main(){
//	freopen("qwqwqwqwq.in","r",stdin);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>x>>y>>z;
		if(x==y)continue;
		add_e(x,y,z);
		add_e(y,x,z);
	} 
	kruskal();
//	cout<<"_______________"<<endl;
//	for(int i=1;i<=tree_num;i++)cout<<tree[i].u<<" "<<tree[i].v<<endl;
//	cout<<"_______________"<<endl;
	S.clear();
	Len[1]=-1;
	pre(1);
	cut(1,1);
//	for(int i=1;i<=n;i++)cout<<top[i]<<" ";
//	cout<<"______"<<endl;
//	cout<<"sum: "<<sum_l<<endl;
	for(int i=1;i<=e_num;i++){
		if(e[i].op)continue;
		pair<ll,ll> reg=max_l(e[i].u,e[i].v);
//		cout<<e[i].u<<" -- "<<e[i].v<<endl; 
//		cout<<reg.first<<" , "<<reg.second<<endl;
		if(reg.first==e[i].w&&reg.second==-1)continue;
		if(reg.first==-1)continue;
		if(reg.first==e[i].w&&reg.second==e[i].w)continue;
		if(reg.first==e[i].w&&reg.second!=-1)Ans=min(Ans,sum_l-reg.second+e[i].w);
		else Ans=min(Ans,sum_l-reg.first+e[i].w);
	}
	cout<<Ans;
	return 0;
}

2023/11/4 14:16
加载中...