模拟链表,稀疏图的dij
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) ((x)<<1)
#define r(x) ((x)<<1|1)
#define lowbit(x) ((x)&(-(x)))
#define abs(x) ((x)>=0?(x):(-(x)))
#define ms(a,b) memset(a,b,sizeof(a))
#define NSYNC std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
using namespace std;
const int maxn = 1000010;
struct edges {
int end, val,next;
} e[maxn],re[maxn];
struct node {
int my, val;
node(int vv,int dd):my(vv),val(dd){}
bool operator<(const node &m) const {
return val > m.val;
}
};
ll n,m,len,rlen,head[maxn],rhead[maxn],d[maxn];
int uesd[maxn];
ll ans;
int a, b, c,t;
void add(int start, int end, int val) {
e[len].end = end;
e[len].next = head[start];
e[len].val = val;
head[start] = len++;
}
void radd(int start, int end, int val) {
re[rlen].end = end;
re[rlen].next = rhead[start];
re[rlen].val = val;
rhead[start] = rlen++;
}
void dij(int s) {
ms(d, INF);
ms(uesd, 0);
d[s] = 0;
priority_queue<node> q;
q.push(node(s, 0));
while (!q.empty()) {
s = q.top().my;
q.pop();
if (uesd[s])continue;
uesd[s] = 1;
for (int j = head[s]; j; j = e[j].next) {
int end = e[j].end;
int val = e[j].val;
if (!uesd[end] && d[end] > d[s] + val) {
d[end] = d[s] + val;
q.push(node(end, d[end]));
}
}
}
}
int main(){
scanf("%d", &t);
while (t--) {
len = rlen = 1;
ms(head, 0);
ms(rhead, 0);
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
radd(b, a, c);
}
ans = 0;
dij(1);
for (int i = 1; i <= n; i++) ans += d[i];
memcpy(head, rhead, sizeof(rhead));
memcpy(e, re, sizeof(re));
dij(1);
for (int i = 1; i <= n; i++)ans += d[i];
printf("%lld\n", ans);
}
return 0;
}