萌新求助
查看原帖
萌新求助
141599
sinsop90楼主2020/7/20 11:15
#include<bits/stdc++.h>
using namespace std;
int n,m,up[200005][35];
int dep[200005];
int num = 0,pre[200005],head[200005],maxi[2005][2005],mini[2005][2005];
bool flag[200005];
struct node{
	int from,to,leng;
	int next;
}e[200005];
int find(int x){
	if(x==pre[x]) return x;
	else return find(pre[x]);
}
void unionn(int x,int y){
	int t = find(x);
	int t1 = find(y);
	if(t!=t1){
		pre[t] = pre[t1];
	}
}
bool cmp(node &a,node &b){
	return a.leng>b.leng;
}
void init(){
	for(int i=1;i<=n;i++){
		pre[i] = i;
	}
}
void dfs(int u,int fa){
	up[u][0] = fa;
	for(int i=head[u];i!=-1;i = e[i].next){
		int to = e[i].to;
		if(to==fa){
			continue;
		}
		dfs(e[i].to,u);
	}
}
void cal()
{
    for(int i=1;i<=18;++i)
        for(int j=1;j<=n;++j)
        {
            up[j][i]=up[up[j][i-1]][i-1];
            maxi[j][i]=max(maxi[j][i-1],maxi[up[j][i-1]][i-1]);
            mini[j][i]=max(mini[j][i-1],mini[up[j][i-1]][i-1]);
            if(maxi[j][i-1]>maxi[up[j][i-1]][i-1])mini[j][i]=max(mini[j][i],maxi[up[j][i-1]][i-1]);
            else if(maxi[j][i-1]<maxi[up[j][i-1]][i-1])mini[j][i]=max(mini[j][i],maxi[j][i-1]);
        }
}
int lca(int x,int y)
{
    if(dep[x]<dep[y])swap(x,y);
    for(int i=18;i>=0;--i)
        if(dep[up[x][i]]>=dep[y])
            x=up[x][i];
    if(x==y)return x;
    for(int i=18;i>=0;--i)
        if(up[x][i]^up[y][i])
            x=up[x][i],y=up[y][i];
    return up[x][0];
}
void add(int fro,int t,int len){
	e[++num].from = fro;
	e[num].to = num;
	e[num].leng = len;
	e[num].next = head[fro];
	head[fro] = num;
}
int qmax(int u,int v,int maxx)
{
    int ans=-2147483647;
    for(int i=18;i>=0;--i)
    {
        if(dep[up[u][i]]>=dep[v])
        {
            if(maxx!=maxi[u][i])ans=max(ans,maxi[u][i]);
            else ans=max(ans,mini[u][i]);
            u=up[u][i];
        }
    }
    return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	init();
	sort(e+1,e+m+1,cmp);
	int cnt = 0;
	for(int i=1;i<=m;i++){
		int t = find(e[i].from);
		int t1 = find(e[i].to);
		if(t!=t1){
			pre[t] = t1;
			cnt+=e[i].leng;
			flag[i] = true;
		}
	}
	dep[1] = 1;
	mini[1][0] = -2147483647;
	dfs(1,-1);
	cal();
	int ansn=0;
	for(int i=1;i<=m;++i)
    {
        if(!flag[i])
        {
            int u=e[i].from;
            int v=e[i].to;
            int d=e[i].leng;
            int lcan=lca(u,v);
            int maxu=qmax(u,lcan,d);
            int maxv=qmax(v,lcan,d);
            ansn=min(ansn,cnt-max(maxu,maxv)+d);
        }
    }

    printf("%lld",ansn);
}

哪里错了啊(原谅代码的顺序

2020/7/20 11:15
加载中...