题目大意
有一些点和一些边,修建一条边有花费,但可以是连接的两个点有收益,花费远大于收益,求最小花费使图连通。
解题思路
显然每条边的花费(计算了收益的影响)是一定的,可以直接最小生成树。
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 ;
}