思路:ans = 每条边(u,v)*v的子树节点的w = 所有的dist[v]*w[v]之和;
#include<iostream> #include<queue> #include<cstdio> #include<cstring> #define MAX 500005 const long long int INF = 100000000000000; using namespace std; typedef struct{ int to, next, w; }Node; Node edge[MAX*2]; queue<int>q; long long int vis[MAX], head[MAX], dist[MAX], W[MAX]; long long int ans; void init(int n){ memset(vis, 0, sizeof(vis)); memset(head, -1, sizeof(head)); for(int i = 1;i <= n;i ++) dist[i] = INF; dist[1] = 0; } void spfa(int s){ while(!q.empty()) q.pop(); q.push(s); vis[s] = 1; while(!q.empty()){ int p =q.front(); q.pop(); vis[p] = 0; for(int i = head[p];i != -1;i = edge[i].next){ int v = edge[i].to; if(dist[v] > dist[p] + edge[i].w){ dist[v] = dist[p] + edge[i].w; if(!vis[v]){ q.push(v); vis[v] = 1; } } } } } void AddEdge(int i, int u, int v, int w){ edge[i].to = v; edge[i].w = w; edge[i].next = head[u]; head[u] = i; } int main(){ int T, n, e, u, v, price, k; /* freopen("in.c", "r", stdin); */ scanf("%d", &T); while(T--){ scanf("%d%d", &n, &e); init(n); for(int i = 1;i <= n;i ++) cin >> W[i]; k = 0; for(int i = 0;i < e;i ++){ scanf("%d%d%d", &u, &v, &price); AddEdge(k++, u, v, price); AddEdge(k++, v, u, price); } spfa(1); int flag = 0; ans = 0LL; for(int i = 2;i <= n;i ++){ if(dist[i] == INF){ flag = 1; break; } ans += W[i]*dist[i]; } if(!flag) cout << ans << endl; else cout << "No Answer "; } return 0; }