#include <iostream>
#include <cstdio>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXPOINT 1010
struct E {
int next;
int c;
};
vector<struct E> edges[MAXPOINT];
// 第一层可使用map映射节省空间 K < N
int Dis[MAXPOINT][MAXPOINT];
void Dijkstra(int start, int N) {
bool mark[MAXPOINT];
for (int i = 1; i <= N; ++i) {
Dis[start][i] = -1;
mark[i] = false;
}
Dis[start][start] = 0;
mark[start] = true;
int newP = start;
for (int i = 2; i <= N; i++) {
for (int j = 0; j < edges[newP].size(); ++j) {
int next = edges[newP][j].next;
int c = edges[newP][j].c;
if (mark[next]) continue;
if (Dis[start][next] == -1 || Dis[start][next] > Dis[start][newP] + c) {
Dis[start][next] = Dis[start][newP] + c;
}
}
int min = INT_MAX;
for (int j = 1; j <= N; ++j) {
if (mark[j]) continue;
if (Dis[start][j] == -1) continue;
if (Dis[start][j] < min) {
min = Dis[start][j];
newP = j;
}
}
mark[newP] = true;
}
return;
}
int main(int argc, char** argv) {
int T;
scanf("%d", &T);
while (T--) {
int N, M, K;
scanf("%d %d %d", &N, &M, &K);
for (int i = 1; i <= N; ++i) edges[i].clear();
// for (int i = 0; i < N; ++i) vector<struct E>().swap(edges[i]);
while (M--) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
struct E tmp;
tmp.c = w;
tmp.next = v;
edges[u].push_back(tmp);
tmp.next = u;
edges[v].push_back(tmp);
}
int Tar[10];
for (int i = 0; i < K; ++i) scanf("%d", &Tar[i]);
sort(Tar, Tar + K); // 重要?!不排序会得到错误答案
// 对每个点进行Dijkstra算法处理
Dijkstra(1, N);
for (int i = 0; i < K; ++i) Dijkstra(Tar[i], N);
// 使用全排列计算最小值
int res = INT_MAX;
do {
int tmp = Dis[1][Tar[0]];
if (tmp == -1) continue;
for (int i = 0; i < K - 1; ++i) {
if (Dis[Tar[i]][Tar[i + 1]] == -1) {
tmp = INT_MAX;
break;
}
tmp += Dis[Tar[i]][Tar[i + 1]];
}
if (tmp < res) res = tmp;
} while (next_permutation(Tar, Tar + K));
printf("%d\n", res);
}
return 0;
}
302. 网络传输-网研14
最新推荐文章于 2022-11-15 11:06:06 发布