题目的意思是让那你建立一颗圣诞树。
圣诞树以1为头结点。
圣诞树每条边的花费为当前边的权值乘以当前边的子树的节点的权值和。
那么就相当于求每个节点乘以节点到根节点的最短路的和。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define maxn 210000
#define maxeg 55000
#define maxpt 55000
#define INF -1
#define LL long long
struct G
{
int num;
int head[maxpt];
struct list{int u,v,next;LL w;}edge[maxeg*2+1000];
void init(){
memset(head,-1,sizeof(head));
num=0;
}
void add(int u,int v,LL w){
edge[num].u=u;edge[num].v=v;edge[num].w=w;
edge[num].next=head[u];head[u]=num++;
}
}gra;
struct list
{
int u;
LL num;
bool operator < (const list &a)const
{
return num>a.num;
}
}p,pp;
LL val[maxpt];
priority_queue<list>que;
int n,m;
void dij(int x)
{
int i;
while(!que.empty())que.pop();
int vis[maxpt];
LL dis[maxpt];
for(i=0;i<maxpt;i++)
{
dis[i]=INF;
}
p.u=x;p.num=0;
que.push(p);
while(!que.empty())
{
p=que.top();que.pop();
int u=p.u;
if(dis[u]>p.num||dis[u]==-1)dis[u]=p.num;
else continue;
for(i=gra.head[u];i!=-1;i=gra.edge[i].next)
{
int v=gra.edge[i].v;
LL w=gra.edge[i].w;
pp.u=v;
pp.num=w+p.num;
que.push(pp);
}
}
LL ans=0;
for(i=1;i<=n;i++)
{
ans=ans+val[i]*dis[i];
if(dis[i]==INF)
{
cout<<"No Answer"<<endl;
return ;
}
}
cout<<ans<<endl;
}
int main()
{
int i,a,b,s,t,k;
int T;
LL c;
scanf("%d",&T);
while(T--)
{
gra.init();
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%lld",&val[i]);
}
for(i=1;i<=m;i++)
{
scanf("%d%d%lld",&a,&b,&c);
gra.add(a,b,c);
gra.add(b,a,c);
}
dij(1);
}
return 0;
}