二分+枚举+最短路。。。不错的题。。。
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 105
#define maxm 10005
#define eps 1e-10
#define mod 1000000007
#define INF 1e9+10
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
struct Edge
{
int v, c;
Edge *next;
}pool[maxm], *edges, *H[maxn];
struct node
{
int id, d;
bool operator < (const node& b) const {
return d > b.d;
}
}now, tmp;
priority_queue<node> q;
int dist[maxn], vis[maxn];
int h[maxn], hh[maxn];
int n, m;
void addedges(int u, int v, int c)
{
edges->v = v;
edges->c = c;
edges->next = H[u];
H[u] = edges++;
}
void init(void)
{
edges = pool;
memset(H, 0, sizeof H);
}
int cmp(int a, int b)
{
return a < b;
}
void read(void)
{
int a, b, c;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &h[i]), hh[i] = h[i];
for(int i = 1; i <= m; i++) {
scanf("%d%d%d", &a, &b, &c);
addedges(a, b, c);
addedges(b, a, c);
}
sort(h+1, h+n+1, cmp);
}
int dijstra(int s, int low, int high)
{
for(int i = 1; i <= n; i++) dist[i] = INF, vis[i] = 0;
tmp.id = s, tmp.d = 0;
if(hh[s] >= low && hh[s] <= high) q.push(tmp);
dist[s] = 0;
while(!q.empty()) {
now = q.top(), q.pop();
int x = now.id, d = now.d;
if(vis[x]) continue;
vis[x] = 1;
for(Edge *e = H[x]; e; e = e->next) {
if(dist[e->v] > dist[x] + e->c && hh[e->v] >= low && hh[e->v] <= high) {
dist[e->v] = dist[x] + e->c;
tmp.id = e->v, tmp.d = dist[e->v];
q.push(tmp);
}
}
}
return dist[n];
}
void work(void)
{
int top, bot, low, mid, res, ans = h[n], t;
for(int i = 1; i <= n; i++) {
low = h[i], top = h[n], bot = h[i], res = -1;
//printf("AAA %d\n", i);
//printf("%d %d\n", dijstra(1, 3, 5), dist[n]);
while(top >= bot) {
mid = (top + bot) >> 1;
if(dijstra(1, low, mid) != INF) res = mid, top = mid-1;
else bot = mid+1;
}
if(res != -1 && res - low <= ans) {
if(res - low < ans) ans = res - low, t = dijstra(1, low, res);
else t = min(t, dijstra(1, low, res));
}
}
printf("%d %d\n", ans, t);
}
int main(void)
{
int _;
while(scanf("%d", &_)!=EOF) {
while(_--) {
init();
read();
work();
}
}
return 0;
}