【链接】h在这里写链接
【题意】
给你n个城市,m条边.
选择其中的r(r<=8)个城市。
然后让你从某个城市开始,遍历这r个城市.
问你最小花费。
【题解】
做SPFA的时候,加一维,记录的是,当前走过这r个点中的哪些点;
枚举起点就好。
【错的次数】
1
【反思】
在这了写反思
【代码】
#include <bits/stdc++.h>
using namespace std;
const int N = 200;
const int INF = 0x3f3f3f3f;
int n, m, r, ans = INF;
int bh[N + 10], dis[N + 10][256 + 10];
vector <pair<int, int> > G[N + 10];
queue <pair <int, int> > dl;
map <pair<int, int>, int> dic;
void in() {
cin >> n >> m >> r;
for (int i = 1; i <= r; i++) {
int x;
cin >> x;
bh[x] = i;
}
for (int i = 1; i <= m; i++) {
int x, y, z;
cin >> x >> y >> z;
G[x].push_back(make_pair(y, z));
G[y].push_back(make_pair(x, z));
}
}
void bfs() {
while (!dl.empty()) {
int x = dl.front().first, sta = dl.front().second;
dic[make_pair(x, sta)] = 0;
dl.pop();
for (pair<int, int> temp : G[x]) {
int y = temp.first, cost = temp.second, tsta = sta;
if (bh[y]) tsta |= (1 << (bh[y] - 1));
if (dis[y][tsta] > dis[x][sta] + cost) {
dis[y][tsta] = dis[x][sta] + cost;
if (dic[make_pair(y, tsta)] == 0) {
dl.push(make_pair(y, tsta));
}
}
}
}
}
void get_ans() {
memset(dis, INF, sizeof dis);
for (int i = 1; i <= n; i++)
if (bh[i]) {
dis[i][1 << (bh[i] - 1)] = 0;
dl.push(make_pair(i, 1 << (bh[i] - 1)));
dic.clear();
dic[make_pair(i, 1 << (bh[i] - 1))] = 1;
bfs();
}
for (int i = 1; i <= n; i++)
if (bh[i])
ans = min(ans, dis[i][(1 << r) - 1]);
}
void out() {
cout << ans << endl;
}
int main() {
//freopen("F:\rush.txt", "r", stdin);
ios::sync_with_stdio(0), cin.tie(0);
in();
get_ans();
out();
return 0;
}