萌新求助 P4180 [BJWC2010]严格次小生成树
  • 板块学术版
  • 楼主Peter3245127684
  • 当前回复1
  • 已保存回复1
  • 发布时间2020/7/19 22:06
  • 上次更新2023/11/6 22:48:04
查看原帖
萌新求助 P4180 [BJWC2010]严格次小生成树
223362
Peter3245127684楼主2020/7/19 22:06
#include<bits/stdc++.h>
#define int long long
#define N 100010
#define M 300010
using namespace std;
const int INF=1e15;
struct Node
{
	int u,v,w,id;
}a[M];
struct node
{
	int to,w,nxt;
}edge[M<<1];
int n,m,cnt,ans=INF,tot,MST;
int head[N],Fa[N],used[N],dep[N],b[N];
int f[N][21],Min1[N][21],Min2[N][21];
template <typename T>
inline T read(T &x)
{
	T flg=1;x=0;
	char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-') flg=-flg;ch=getchar();}
	while(isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*=flg;
}
template <typename T>
inline void write(T x)
{
	if(x<0) x=-x,putchar('-');
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
template <typename T>
inline void writeln(T x) {write(x);puts("");}
template <typename T>
inline void writesp(T x) {write(x);putchar(' ');}
inline int cmp(Node x,Node y) {return x.w<y.w;}
inline int min(const int &x,const int &y) {return x<y?x:y;}
inline int find(int x) {return Fa[x]==x?x:Fa[x]=find(Fa[x]);}
inline void add(int u,int v,int w)
{
	edge[++cnt].to=v;
	edge[cnt].w=w;
	edge[cnt].nxt=head[u];
	head[u]=cnt;
}
inline int Fir(int t1,int t2,int t3,int t4)
{
	return min(t1,min(t2,min(t3,t4)));
}
inline int Sec(int t1,int t2,int t3,int t4)
{
	int t=min(t1,min(t2,min(t3,t4)));
	int tmp=INF;
	if(t1^t) tmp=min(tmp,t1);
	if(t2^t) tmp=min(tmp,t2);
	if(t3^t) tmp=min(tmp,t3);
	if(t4^t) tmp=min(tmp,t4);
	return tmp;
}
inline void dfs(int u,int fa,int w)
{
	dep[u]=dep[fa]+1;f[u][0]=fa;
	Min1[u][0]=w;Min2[u][0]=w;
	for(register int i=1;i<=20;++i)
	  {
	  	f[u][i]=f[f[u][i-1]][i-1];
	  	int t1=Min1[u][i-1],t2=Min1[f[u][i-1]][i-1];
	  	int t3=Min2[u][i-1],t4=Min2[f[u][i-1]][i-1];
	  	Min1[u][i]=Fir(t1,t2,t3,t4);
	  	Min2[u][i]=Sec(t1,t2,t3,t4);
	  }
	for(register int i=head[u];i;i=edge[i].nxt)
	  {
	  	int v=edge[i].to;
	  	if(v==fa) continue;
	  	dfs(v,u,edge[i].w);
	  }
}
inline int LCA(int x,int y,int val)
{
	int len=0;
	if(dep[x]<dep[y]) swap(x,y);
	for(register int i=20;i>=0;--i)
	  if(dep[f[x][i]]>=dep[y])
	    {
	      b[++len]=Min1[x][i];
	      b[++len]=Min2[x][i];
          x=f[x][i];
		}
	for(register int i=20;i>=0;--i)
	  if(f[x][i]^f[y][i])
	    {
	      b[++len]=Min1[x][i];b[++len]=Min2[x][i];
	      b[++len]=Min1[y][i];b[++len]=Min2[y][i];
	      x=f[x][i],y=f[y][i];
		}
	b[++len]=Min1[x][0];b[++len]=Min2[x][0];
	b[++len]=Min1[y][0];b[++len]=Min2[y][0];
	sort(b+1,b+len+1);
	for(register int i=len;i>=1;--i)
	  if(b[i]<val) return b[i];
	return INF;
}
signed main()
{
	read(n);read(m);
	for(register int i=1;i<=m;++i)
	  read(a[i].u),read(a[i].v),read(a[i].w);
	sort(a+1,a+m+1,cmp);
	for(register int i=1;i<=n;++i) Fa[i]=i;
	for(register int i=1;i<=m;++i)
	  {
	  	int r1=find(a[i].u);
	  	int r2=find(a[i].v);
	  	if(r1==r2) continue;
		Fa[r1]=r2;
		MST+=a[i].w;used[i]=1;
		add(a[i].u,a[i].v,a[i].w);
		add(a[i].v,a[i].u,a[i].w);
		if(++tot==n-1) break;
	  }
	dfs(1,0,INF);
	for(register int i=1;i<=m;++i)
	  if(!used[i])
	    {
	      int u=a[i].u,v=a[i].v,w=a[i].w;
	      int lca=LCA(u,v,w);
	      ans=min(ans,MST-lca+w);
		}
	write(ans);
	return 0;
}
2020/7/19 22:06
加载中...