#include using namespace std; const int N = 1e5 + 10, M = N << 1; typedef pair PII; int n, m, s; int dist[2 * N]; // 链式前向星,因为是两份图,所以啥啥都是两份 int h[2 * N], ne[2 * M], e[2 * M], w[2 * M], idx; bool st[N]; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++; } void dijkstra(int s) { memset(dist, 0x3f, sizeof dist); dist[s] = 0; priority_queue, greater> q; // 小顶堆 q.push({0, s}); while (q.size()) { auto t = q.top(); q.pop(); int u = t.second; if (st[u]) continue; st[u] = 1; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] > dist[u] + w[i]) { dist[j] = dist[u] + w[i]; q.push({dist[j], j}); } } } } int main() { memset(h, -1, sizeof h); cin >> n >> m; while (m--) { int a, b, c; cin >> a >> b >> c; add(a, b, c); // 正图 add(b + n, a + n, c); // 反图 } int res = 0; // 单源最短路,就是从1出发,到达其它n-1个点的最短距离 dijkstra(1); for (int i = 1; i <= n; i++) res += dist[i]; // 从n-1个节点,返回1号节点,就是多源最短路 // 通过建反图,将多源最短路转化为单源最短路 // 建反图时,所以节点号+n处理,这样1号节点就变成1+n号节点,其它n-1个节点向1号节点的多源最短路就变成了 // 从1+n~ [2+n,3+n,...,n+n]的最短路径了 dijkstra(1 + n); for (int i = 1 + n; i <= 2 * n; i++) res += dist[i]; printf("%d\n", res); return 0; }