不懂就问,这样分讨正常吗
查看原帖
不懂就问,这样分讨正常吗
246927
LG_kemeng楼主2023/11/3 18:28
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 1e18
const int N=1e5+10,M=3e5+10;
int n,m;
struct edge{
	int u,v,w;
	inline bool operator<(const edge x) const
	{
		return w<x.w;
	}
};
struct sub_small{
	int tot,v[M<<1],w[M<<1],first[N],nxt[M<<1];
	int fa[N][20],mx1[N][20],mx2[N][20],dep[N];
	vector<edge> rest;
	int minimum=0,ans=inf;
	inline void add_edge(edge x)
	{
		register int from=x.u,to=x.v,val=x.w;
		tot+=2;
		v[tot]=to,v[tot^1]=from;
		w[tot]=val,w[tot^1]=val;
		nxt[tot]=first[from],first[from]=tot;
		nxt[tot^1]=first[to],first[to]=tot^1;
	}
	inline void dfs(register int x=1)
	{
		for(register int i=0;fa[x][i];i++)
		{
			fa[x][i+1]=fa[fa[x][i]][i];
			if(mx1[x][i]>mx1[fa[x][i]][i])
			{
				mx2[x][i+1]=max(mx1[fa[x][i]][i],mx2[x][i]);
				mx1[x][i+1]=mx1[x][i];
			}
			else if(mx1[fa[x][i]][i]>mx1[x][i])
			{
				mx2[x][i+1]=max(mx1[x][i],mx2[fa[x][i]][i]);
				mx1[x][i+1]=mx1[fa[x][i]][i];
			}
			else
			{
				mx2[x][i+1]=max(mx2[x][i],mx2[fa[x][i]][i]);
				mx1[x][i+1]=mx1[x][i];
			}
		}
		dep[x]=dep[fa[x][0]]+1;
		for(register int i=first[x];i;i=nxt[i])
			if(!dep[v[i]])
			{
				fa[v[i]][0]=x;
				mx1[v[i]][0]=w[i];
				dfs(v[i]);
			}
	}
	inline pair<int,int> maximum(edge e)
	{
		register int x=e.u,y=e.v;
		register int maxx=0,submax=0;
		if(dep[x]<dep[y]) swap(x,y);
		register int d=dep[x]-dep[y];
		for(register int i=0;d;i++,d>>=1)
			if(d&1)
			{
				if(mx1[x][i]>maxx)
				{
					submax=max(maxx,mx2[x][i]);
					maxx=mx1[x][i];
				}
				else if(mx1[x][i]<maxx)
				{
					submax=max(submax,mx1[x][i]);
				}
				else
				{
					submax=max(submax,mx2[x][i]);
				}
				x=fa[x][i];
			}
		if(x==y) return make_pair(maxx,submax);
		for(register int i=18;i>=0;i--)
			if(fa[x][i]^fa[y][i])
			{
				if(max(mx1[x][i],mx1[y][i])>maxx)
				{
					if(mx1[x][i]>mx1[y][i])
					{
						submax=max(maxx,max(mx2[x][i],mx1[y][i]));
						maxx=mx1[x][i];
					}
					else if(mx1[y][i]>mx1[x][i])
					{
						submax=max(maxx,max(mx2[y][i],mx1[x][i]));
						maxx=mx1[y][i];
					}
					else
					{
						submax=max(submax,max(mx2[x][i],mx2[y][i]));
						maxx=mx1[x][i];
					}
				}
				else if(max(mx1[x][i],mx1[y][i])<maxx)
				{
					submax=max(submax,max(mx1[x][i],mx1[y][i]));
				}
				else
				{
					if(mx1[x][i]^maxx)
					{
						submax=max(submax,mx1[x][i]);
					}
					if(mx1[y][i]^maxx)
					{
						submax=max(submax,mx1[y][i]);
					}
					submax=max(submax,max(mx2[x][i],mx2[y][i]));
				}
				x=fa[x][i],y=fa[y][i];
			}
		if(max(mx1[x][0],mx1[y][0])>maxx)
		{
			if(mx1[x][0]>mx1[y][0])
			{
				submax=max(maxx,max(mx2[x][0],mx1[y][0]));
				maxx=mx1[x][0];
			}
			else if(mx1[y][0]>mx1[x][0])
			{
				submax=max(maxx,max(mx2[y][0],mx1[x][0]));
				maxx=mx1[y][0];
			}
			else
			{
				submax=max(submax,max(mx2[x][0],mx2[y][0]));
				maxx=mx1[x][0];
			}
		}
		else if(max(mx1[x][0],mx1[y][0])<maxx)
		{
			submax=max(submax,max(mx1[x][0],mx1[y][0]));
		}
		else
		{
			if(mx1[x][0]^maxx)
			{
				submax=max(submax,mx1[x][0]);
			}
			if(mx1[y][0]^maxx)
			{
				submax=max(submax,mx1[y][0]);
			}
			submax=max(submax,max(mx2[x][0],mx2[y][0]));
		}
		return make_pair(maxx,submax);
	}
	inline void work()
	{
		dfs();
		for(auto e:rest)
		{
			if(maximum(e).first^e.w) ans=min(ans,minimum-maximum(e).first+e.w);
			else if(maximum(e).second) ans=min(ans,minimum-maximum(e).second+e.w);
		}
		printf("%lld\n",ans);
	}
}S;
struct kruskal{
	int fa[N];
	edge e[M];
	inline void _kruskal()
	{
		for(register int i=1;i<=n;i++)
			fa[i]=i;
	}
	inline int gf(register int x)
	{
		return fa[x]==x?x:fa[x]=gf(fa[x]);
	}
	inline void merge(edge x)
	{
		fa[gf(x.u)]=gf(x.v);
	}
	inline void work()
	{
		_kruskal();
		sort(e+1,e+1+m);
		for(register int i=1;i<=m;i++)
		{
			if(e[i].u==e[i].v) continue;
			if(gf(e[i].u)==gf(e[i].v))
			{
				S.rest.emplace_back(e[i]);
			}
			else
			{
				S.add_edge(e[i]);
				S.minimum+=e[i].w;
				merge(e[i]);
			}
		}
	}
}P;
signed main(void)
{
	scanf("%lld%lld",&n,&m);
	for(register int i=1;i<=m;i++)
	{
		register int x,y,z;
		scanf("%lld%lld%lld",&x,&y,&z);
		P.e[i]={x,y,z};
	}
	P.work();S.work();
	return 0;
}
2023/11/3 18:28
加载中...