题目其实还是设了不少障碍
但算法很容易看出来就是最小生成树 可是思路还挺巧妙的
手残看了一眼题解,不过我还是相信我可以慢慢想出来的
根据题意不难发现 因为走来回 每条边会被走两次且要待一次两边的点 所以边权=原边权*2+两点的点权
对于神奇的题意:每个晚上。。我觉得的确有点问题,幸好看了黄学长题解,其实应该就是只是选一个起点和终点的样子吧。。所以选择起床那里就选点权最小的就好了。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define inf 1000000000
using namespace std;
struct edge{int x,y,c;}a[100010];
int Cmp(edge x1,edge x2){return x1.c<x2.c;}
int p[10010],f[10010];
int fa(int x){return f[x]==x?x:f[x]=fa(f[x]);}
int main()
{
int n,m,i,fx,fy;
scanf("%d%d",&n,&m);
int ans=inf,s=0;
for(i=1;i<=n;i++)
{
scanf("%d",&p[i]),f[i]=i;
ans=min(ans,p[i]);
}
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].c);
a[i].c=a[i].c*2+p[a[i].x]+p[a[i].y];
}
sort(a+1,a+1+m,Cmp);
for(i=1;i<=m;i++)
{
fx=fa(a[i].x),fy=fa(a[i].y);
if(fx==fy)continue;
f[fx]=fy, s++, ans+=a[i].c;
if(s==n-1)break;
}
printf("%d\n",ans);
return 0;
}