建出MST即可,但先要用dijkstra求出每个点到达的最近基站。
可预先将所有基站放入堆中迭代。
// Program written by Liu Zhaozhou ~~~ #include <bits/stdc++.h> #include <tr1/unordered_map> #define lowbit(x) (x & -x) using namespace std; inline char gc(void) { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; } #define gc() getchar() template <class T> inline void read(T &x) { T f = 1; x = 0; static char c = gc(); for (; !isdigit(c); c = gc()) if (c == '-') f = -f; for (; isdigit(c); c = gc()) x = (x << 1) + (x << 3) + (c & 15); x *= f; } inline void readstr(char *s) { do *s = gc(); while ((*s == ' ') || (*s == '\n') || (*s == '\r')); do *(++s) = gc(); while ((~*s) && (*s != ' ') && (*s != '\n') && (*s != '\r')); *s = 0; return; } inline void readch(char&x) { while (isspace(x = gc())); } template <class T> inline void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + 48); } template <class T> inline void writeln(T x, char c = '\n') { write(x); putchar(c); } template <class T> inline void chkmax(T &x, const T y) { x > y ? x = x : x = y; } template <class T> inline void chkmin(T &x, const T y) { x < y ? x = x : x = y; } #define Ms(arr, opt) memset(arr, opt, sizeof(arr)) #define Mp(x, y) make_pair(x, y) typedef long long ll; const int Maxn = 1e5 + 5, Maxm = 1e6 + 5; int n, m, k, cnt = 0, head[Maxn], ver[Maxm], nxt[Maxm], edge[Maxm]; inline void AddEdge(int u, int v, int w) { ver[++cnt] = v, edge[cnt] = w, nxt[cnt] = head[u], head[u] = cnt; ver[++cnt] = u, edge[cnt] = w, nxt[cnt] = head[v], head[v] = cnt; } struct state { int u, d; state(void) { u = d = 0; } state(int _u, int _d) : u(_u), d(_d) {} inline bool operator < (const state&rhs) const { return d > rhs.d; } }; int c[Maxn], nrc[Maxn], dis[Maxn]; bool vis[Maxn]; inline void dijkstra(void) { priority_queue <state> q; Ms(dis, 0x3f); for (int i = 1; i <= k; i++) dis[c[i]] = 0, nrc[c[i]] = c[i], q.push(state(c[i], 0)); while (!q.empty()) { int u = q.top().u; q.pop(); if (vis[u]) continue; vis[u] = true; for (int i = head[u]; i; i = nxt[i]) { if (dis[ver[i]] > dis[u] + edge[i]) { dis[ver[i]] = dis[u] + edge[i]; nrc[ver[i]] = nrc[u]; q.push(state(ver[i], dis[ver[i]])); } } } } struct Edge { int u, v, w; Edge(void) { u = v = w = 0; } Edge(int _u, int _v, int _w) : u(_u), v(_v), w(_w) {} inline bool operator < (const Edge&rhs) const { return w < rhs.w; } } e[Maxm]; int f[Maxn]; inline int getf(int x) { return f[x] == x ? x : f[x] = getf(f[x]); } signed main(void) { read(n), read(m); for (int i = 1, u, v, w; i <= m; i++) read(u), read(v), read(w), AddEdge(u, v, w); read(k); for (int i = 1; i <= k; i++) read(c[i]); dijkstra(); int tot = 0; for (int u = 1; u <= n; u++) for (int i = head[u]; i; i = nxt[i]) if (nrc[u] != nrc[ver[i]]) e[++tot] = Edge(nrc[u], nrc[ver[i]], dis[u] + dis[ver[i]] + edge[i]); sort(e + 1, e + tot + 1); int ans = 0; for (int i = 1; i <= n; i++) f[i] = i; for (int i = 1; i <= tot; i++) { int u = getf(e[i].u), v = getf(e[i].v), w = e[i].w; if (u != v) f[u] = v, ans = w; } writeln(ans); return 0; } /**/