Description
Analysis
大水题。
将每条边的边权减去它连接的两个点的点权,再做最小生成树。
Code
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int N=100010;
int n,m,fa[N];
ll a[N];
struct edge
{
int x,y;
ll z;
}b[N];
bool cmp(edge a,edge b){return a.z<b.z;}
int getfa(int v)
{
if(!fa[v]) return v;
return fa[v]=getfa(fa[v]);
}
int main()
{
scanf("%d %d",&n,&m);
fo(i,1,n) scanf("%lld",&a[i]);
fo(i,1,m)
{
scanf("%d %d %lld",&b[i].x,&b[i].y,&b[i].z);
b[i].z-=a[b[i].x]+a[b[i].y];
}
sort(b+1,b+m+1,cmp);
int k=0;
ll ans=0;
fo(i,1,m)
{
int fx=getfa(b[i].x),fy=getfa(b[i].y);
if(fx==fy) continue;
k++,ans+=b[i].z;
if(k>=n-1) break;
fa[fy]=fx;
}
printf("%lld",ans);
return 0;
}