这个题太秀了
卡自闭队友
蔡哥树剖lca搞
让我心心念念好几天
原来是这么个玩意。
https://ac.nowcoder.com/acm/contest/1221/H
题意:给出一个n个点m条边的图,每个边有权值w,你可以删除一些边,使得剩下的边的最小生成树大小不变并且这个图的最小生成树是独一无二的。现在我们想要知道删除的边的权值和最小是多少?
思路:要形成独一无二的最小生成树,那么就没有别的边可以在构造最小生成树时加入最小生成树。
我们可以在计算最小生成树时求所有可以加入最小生成树的边权和,再减去一个最小生成树的边权和就是答案。
#include<bits/stdc++.h>
using namespace std;
const int M=2e5+5;
using ll =long long;
struct Node{int from,to,w;}e[M];
bool cmp(const Node &a,const Node &b){return a.w<b.w;}
int n,m,d[M];
ll res=0;
int fa(int x){return d[x]==x?x:d[x]=fa(d[x]);}
int main(){
scanf("%d%d",&n,&m);
for(register int i=0;i<=n;i++)d[i]=i;
for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].w);
sort(e+1,e+m+1,cmp);
for(int j,i=1;i<=m;i++){
j=i;
while(j<=m&&e[j].w==e[i].w) j++;
for(int x,y,k=i;k<j;k++){
x=fa(e[k].from);y=fa(e[k].to);
if(x!=y) res+=e[k].w;
}
for(int x,y,k=i;k<j;k++){
x=fa(e[k].from);y=fa(e[k].to);
if(x!=y) d[x]=y,res-=e[k].w;
}
}
cout<<res<<endl;
return 0;
}