//poj3013
/*
站在每个点的角度考虑,答案等于每个点的权重*1到该点的所有的边的权值和
可以证明,1到所有点的最短路构成一颗树。直接跑一遍最短路即可

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
#define ll long long 
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define frr(i,a,b) for(int i=a;i>=b;i--)
#define ms(a,b) memset(a,b,sizeof(a))
#define scfd(a) scanf("%d",a)
#define scflf(a) scanf("%lf",a)
#define scfs(a) scanf("%s",a)
#define ptfd(a) printf("%d\n",a)
#define ptfs(a) printf("%s\n",a)
#define showd(a,b) printf(a"=%d\n",b)
#define showlf(a,b) printf(a"=%lf\n",b)
#define shows(a,b) printf(a"=%s\n",b)
#define mmcp(a,b) memcpy(a,b,sizeof(b))
#define pb(a) push_back(a)
const int MAXN=50005;
ll w[MAXN];
int n,m;
int cases;
struct spfa{
	struct edge{
		int f,t;
		ll d;
	};
	vector<int>g[MAXN];
	vector<edge>e;
	bool vis[MAXN];
	ll d[MAXN];
	void init(){
		fr(i,0,MAXN-1)
			g[i].clear();
		e.clear();
	}
	void add_edge(int f,int t,ll d){
		e.push_back((edge){f,t,d});
		e.push_back((edge){t,f,d});
		g[f].push_back(e.size()-2);
		g[t].push_back(e.size()-1);
	}
	ll solve(){
		ms(vis,false);
		fr(i,0,MAXN-1)
			d[i]=214748364555LL;
		d[1]=0;
		queue<int>q;
		q.push(1);
		vis[1]=true;
		while(!q.empty()){
			int now=q.front();
			q.pop();
			vis[now]=false;
			int size=g[now].size();
			fr(i,0,size-1){
				if(d[e[g[now][i]].t]>d[now]+e[g[now][i]].d){
					d[e[g[now][i]].t]=d[now]+e[g[now][i]].d;
					if(!vis[e[g[now][i]].t]){
						vis[e[g[now][i]].t]=true;
						q.push(e[g[now][i]].t);
					}
				}
			}
		}
		ll ans=0;
		fr(i,1,n){
			if(d[i]==214748364555LL)
				return -1;
			ans+=d[i]*w[i];
		}
		return ans;
	}
}dji;
int main(){
	scfd(&cases);
	while(cases--){
		dji.init();
		scanf("%d%d",&n,&m);
		fr(i,1,n)
			scanf("%lld",&w[i]);
		fr(i,1,m){
			int a,b;
			ll c;
			scanf("%d%d%lld",&a,&b,&c);
			dji.add_edge(a,b,c);
		}
		ll ans=dji.solve();
		if(ans==-1)
			printf("No Answer\n");
		else
			printf("%lld\n",ans);
	}

}
 posted on 2017-09-22 17:00  cylcy  阅读(102)  评论(0编辑  收藏  举报