题目大意
有一些点和一些边,修建一条边有花费,但可以是连接的两个点有收益,花费远大于收益,求最小花费使图连通。
解题思路
显然每条边的花费(计算了收益的影响)是一定的,可以直接最小生成树。
code
using namespace std;
int const maxn=100000,maxm=100000;
int n,m,a[maxn+10],father[maxn+10];
LL read(){
LL val=0;char ch=getchar();
for(;(ch<'0')||(ch>'9');ch=getchar());
for(;(ch>='0')&&(ch<='9');val=val*10+ch-'0',ch=getchar());
return val;
}
struct ed{
int x,y;LL z;
friend bool operator<(ed x,ed y){return x.z<y.z;}
};
ed edge[maxm+10];
int getfather(int x){
if(!father[x])return x;
return father[x]=getfather(father[x]);
}
int main(){
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
//scanf("%d%d",&n,&m);
n=read();m=read();
fo(i,1,n)a[i]=read();//scanf("%d",&a[i]);
fo(i,1,m){
edge[i].x=read();edge[i].y=read();edge[i].z=read();//scanf("%d%d%lld",&edge[i].x,&edge[i].y,&edge[i].z);
edge[i].z-=a[edge[i].x]+a[edge[i].y];
}
sort(edge+1,edge+m+1);
LL ans=0;
fo(i,1,m){
int fx=getfather(edge[i].x),fy=getfather(edge[i].y);
if(fx!=fy){
father[fx]=fy;
ans+=edge[i].z;
}
}
printf("%lld",ans);
return 0;
}