题目:http://www.joyoi.cn/problem/tyvj-1659
发现每条边要走两次,每个点要走它连接的边数次。
所以把边的权值赋成 本身的值+两个端点的点权,求最小生成树即可。
!边权其实是 本身的值*2+两个端点的点权;
别忘了起点要多加一次,所以找一个点权最小的加上即可。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,a[10005],fa[10005],x,y,tmp; long long ans=1005; struct Edge{ int x,y,w; Edge(int x=0,int y=0,int w=0):x(x),y(y),w(w) {} }edge[100005]; bool cmp(Edge x,Edge y){return x.w<y.w;} int find(int a) { if(fa[a]==a)return a; return fa[a]=find(fa[a]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]),fa[i]=i,ans=min(ans,(long long)a[i]); for(int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&tmp); edge[i]=Edge(x,y,a[x]+a[y]+tmp+tmp); } sort(edge+1,edge+m+1,cmp); for(int i=1;i<=m;i++) { int u=edge[i].x,v=edge[i].y; if(find(u)!=find(v)) { // printf("u=%d v=%d plu=%d ",u,v,edge[i].w); fa[fa[u]]=fa[v];ans+=edge[i].w; } } printf("%lld",ans); return 0; }