走过路过的大佬都来HACK一下(40PTS)
查看原帖
走过路过的大佬都来HACK一下(40PTS)
180924
FLAT_LCH楼主2022/10/31 18:22

知道大佬们很忙,不求帮调,只求HACK(卑微)

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <queue>
#include <algorithm>

#define inf 0x3f3f3f3f3f3f3f3f
#define int long long

using namespace std;

struct sidee
{
	int u,v,w;
	bool inq;
}ss[1000000];
struct bian
{
	int v,w,nex;
}s[1000000];
struct node1
{
	int l,r,max1,max2;
}tre[4000000];
struct node
{
	int fa,val;
	int top,son,pos,deep,siz;
	int head;	
}p[1000000];

int n,m,ans=0,summ=0;
int len=0;
int a[1000000],z[10],z1,z2;
pair<int,int>xx;

inline int rd()
{
	int s=0;char x='x';
	while(x<'0'||x>'9')x=getchar();
	while(x>='0'&&x<='9')s=s*10+(x^48),x=getchar();
	return s;
}

int getfa(int u)
{
	if(p[p[u].fa].fa!=p[u].fa)p[u].fa=getfa(p[u].fa);
	return p[u].fa;
}

bool cmp1(sidee x,sidee y)
{
	return x.w<y.w;
}

inline void lian(int u,int v,int w)
{
	len++;s[len].v=v;s[len].w=w;s[len].nex=p[u].head;p[u].head=len;
	len++;s[len].v=u;s[len].w=w;s[len].nex=p[v].head;p[v].head=len;
}

void readd()
{
	n=rd();m=rd();
	for(int i=1;i<=m;i++)
		ss[i].u=rd(),ss[i].v=rd(),ss[i].w=rd();
	sort(ss+1,ss+1+m,cmp1);
	for(int i=1;i<=n;i++)
		p[i].fa=i;
		
	for(int i=1,u,v,j=0;i<=m;i++)
	{
		
		u=getfa(ss[i].u);v=getfa(ss[i].v);
		if(u==v)continue;
		p[v].fa=u;j++;
		summ+=ss[i].w;
		ss[i].inq=true;
		//cout<<ss[i].u<<' '<<ss[i].v<<' '<<ss[i].w<<"intree\n";
		lian(ss[i].u,ss[i].v,ss[i].w);
		if(j>=n-1)break;
	}
	
	for(int i=1;i<=n;i++)
		p[i].fa=0;
	len=0;
}

void Build(int w,int l,int r)
{
	tre[w].l=l;tre[w].r=r;
	if(l==r){tre[w].max1=a[l];tre[w].max2=-inf;;return;}
	Build(w*2,l,(l+r)/2);Build(w*2+1,(l+r)/2+1,r);
	
	z[1]=tre[w*2].max1;z[2]=tre[w*2].max2;z[3]=tre[w*2+1].max1;z[4]=tre[w*2+2].max2;
	sort(z+1,z+1+4);
	tre[w].max1=z[4];
	if(z[3]!=z[4])tre[w].max2=z[3];
	else if(z[2]!=z[4])tre[w].max2=z[2];
	else tre[w].max2=z[1];
}

pair<int,int> Getmax(int w,int l,int r)
{
	if(l>r||tre[w].l>r||tre[w].r<l)return {-inf,-inf};
	if(l<=tre[w].l&&tre[w].r<=r)return {tre[w].max1,tre[w].max2};
	xx=Getmax(w*2,l,r);z[1]=xx.first;z[2]=xx.second;
	xx=Getmax(w*2+1,l,r);z[3]=xx.first;z[4]=xx.second;
	sort(z+1,z+1+4);
	if(z[3]!=z[4])return{z[4],z[3]};
	else if(z[2]!=z[4])return{z[4],z[2]};
	return {z[4],z[1]};
}

void build1(int u)
{
	//cout<<"p["<<u<<"].fa="<<p[u].fa<<"\n";
	p[u].siz=1;
	for(int i=p[u].head,v,w;i;i=s[i].nex)
	{
		v=s[i].v;w=s[i].w;
		if(v==p[u].fa)continue;
		//cout<<u<<' '<<v<<"build1\n";
		p[v].val=w;p[v].deep=p[u].deep+1;p[v].fa=u;
		build1(v);
		p[u].siz+=p[v].siz;
		if(p[v].siz>p[p[u].son].siz)p[u].son=v;
	}
}

void build2(int u)
{
	//cout<<u<<' '<<p[u].top<<"build2\n";
	p[u].pos=++len;
	a[len]=p[u].val;
	if(p[u].son)
	{
		p[p[u].son].top=p[u].top;
		build2(p[u].son);
	}
	for(int i=p[u].head,v,w;i;i=s[i].nex)
	{
		v=s[i].v;w=s[i].w;
		if(v==p[u].fa||v==p[u].son)continue;
		p[v].top=v;
		build2(v);
	}
}

inline pair<int,int> getmax(int x,int y)
{
	int res1=-inf,res2=-inf;
	while(p[x].top!=p[y].top)
	{
		if(p[p[x].top].deep<p[p[y].top].deep)swap(x,y);
		xx=Getmax(1,p[p[x].top].pos,p[x].pos);
		if(xx.second>res1)res2=res1,res1=xx.second;
		else if(xx.second!=res1&&xx.second>res2)res2=xx.second;
		if(xx.first>res1)res2=res1,res1=xx.first;
		else if(xx.first!=res1&&xx.first>res2)res2=xx.first;
		//cout<<x<<' '<<y<<' '<<res1<<' '<<res2<<"getmax"<<endl;
		x=p[p[x].top].fa;
	}
	if(p[x].deep<p[y].deep)swap(x,y);
	xx=Getmax(1,p[y].pos+1,p[x].pos);
	if(xx.second>res1)res2=res1,res1=xx.second;
	else if(xx.second!=res1&&xx.second>res2)res2=xx.second;
	if(xx.first>res1)res2=res1,res1=xx.first;
	else if(xx.first!=res1&&xx.first>res2)res2=xx.first;
	//cout<<x<<' '<<y<<' '<<res1<<' '<<res2<<"end\n\n"<<endl;
	return {res1,res2};
}

void working()
{
	ans=inf;
	for(int i=1,u,v,w;i<=m;i++)
	{
		if(ss[i].inq)continue;
		u=ss[i].u;v=ss[i].v;w=ss[i].w;
		xx=getmax(u,v);
		//cout<<u<<' '<<v<<':'<<w<<",   "<<xx.first<<' '<<xx.second<<endl;
		if(xx.first!=w)ans=min(ans,summ+w-xx.first);
		if(xx.second!=w)ans=min(ans,summ+w-xx.second);
	}
	printf("%lld",ans);
}

signed main()
{
	readd();
	//cout<<summ<<endl;
	p[1].deep=1;p[1].fa=p[1].top=1;
	build1(1);
	build2(1);
	Build(1,1,n);
	working();
	return 0;
}
2022/10/31 18:22
加载中...