1 条题解
-
1
事实上是 最小斯坦利树 的加强版。
#include<bits/stdc++.h> using namespace std; #define int long long const int MAXN = 1e5+5, MAXM = 2e5+5; inline void read(int& a) { int s = 0, w = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') w = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); } a = s * w; } int hd[MAXN], d[MAXN][32]; int n, k, m, cnt, INF; bool vis[MAXN]; struct edge{ int to, dis, nxt; }e[MAXM << 1]; struct dijq{ int x, dis; bool operator<(const dijq &other)const{ return dis > other.dis; } }; priority_queue<dijq> q; void add(int u, int v, int w, int bi = 1){ e[++ cnt].to = v; e[cnt].dis = w; e[cnt].nxt = hd[u]; hd[u] = cnt; if(bi) add(v, u, w, 0); } void dij(int mask){ memset(vis, 0, sizeof vis); while(!q.empty()){ int u = q.top().x; q.pop(); if(vis[u]) continue; vis[u] = 1; for(int i = hd[u]; i; i = e[i].nxt){ int v = e[i].to, w = e[i].dis; if(d[v][mask] > d[u][mask] + w) d[v][mask] = d[u][mask] + w, q.push({v, d[v][mask]}); } } } signed main(){ read(n), read(k), read(m); memset(d, 127 / 3, sizeof d); INF = d[1][1]; for(int i = 1, u; i <= k; ++ i) read(u), d[u][1 << (i - 1)] = 0; for(int i = 1, u, v, w; i <= m; ++ i) read(u), read(v), read(w), add(u, v, w); for(int m1 = 1; m1 < (1 << k); ++ m1){ for(int i = 1; i <= n; ++ i){ for(int m2 = m1 & (m1 - 1); m2; m2 = m1 & (m2 - 1)) d[i][m1] = min(d[i][m1], d[i][m2] + d[i][m1 ^ m2]); if(d[i][m1] < INF) q.push({i, d[i][m1]}); } dij(m1); } int ans = 1e18; for(int i = 1; i <= n; ++ i) ans = min(ans, d[i][(1 << k) - 1]); printf("%lld", ans); }
信息
- ID
- 8810
- 时间
- 3000ms
- 内存
- 250MiB
- 难度
- 8
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者