要点:
- 计算复杂度,对 n 个点做spfa,不会超时
- 不能用邻接矩阵,会超时
- 循环队列的写法
int q[N], hh = 0, tt = 1;
q[0] = x;
while (hh != tt) {
int t = q[hh ++ ];
if (hh == N) hh = 0;
...
q[tt ++ ] = f(t);
if (tt == N) tt = 0;
}
- 永远要记得各个初始化:h, dist
// Problem: 香甜的黄油
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/1129/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
#include<iostream>
#include<algorithm>
#include<cstring> // memset
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 810, M = 2910, INF = 0x3f3f3f3f;
int cow, n, m, idx, id[N];
int dist[N], e[M], ne[M], w[M], h[N];
bool st[N];
void add(int a, int b, int c){
e[idx] = b;
ne[idx] = h[a];
w[idx] = c;
h[a] = idx ++ ;
}
int spfa(int sx) {
int q[N], hh = 0, tt = 1;
memset(dist, 0x3f, sizeof dist);
q[0] = sx;
dist[sx] = 0;
st[sx] = true;
while (hh != tt) {
int t = q[hh ++ ];
if (hh == N) hh = 0;
st[t] = false;
for (int i = h[t]; ~i; i = ne[i]) {
int j = e[i];
if (dist[j] > dist[t] + w[i]) {
dist[j] = dist[t] + w[i];
if (!st[j]) {
q[tt ++ ] = j;
if (tt == N) tt = 0;
st[j] = true;
}
}
}
}
int res = 0;
for (int i = 0; i < cow; i ++ ) {
if (dist[id[i]] == INF) return INF;
res += dist[id[i]];
}
return res;
}
int main(void) {
cin >> cow >> n >> m;
for(int i = 0; i < cow; i ++ ) cin >> id[i];
memset(h, -1, sizeof h);
while (m -- ) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c), add(b, a, c);
}
int res = INF;
for (int i = 1; i <= n; i ++ ) res = min(res, spfa(i));
cout << res << endl;
return 0;
}