https://vjudge.net/problem/Gym-101020H
题意:正常读取方式给你一个图(双向的),然后给你f个点,让你找一条路从1到n的最短路,要求经过f个点(以任意顺序)。
题解:一开始还想dijkstra+dp,发现根本下不了手。后来看了题解,发现只要floyd+next_permutation .Orz
ac代码:
#include<iostream> #include<algorithm> #include<string.h> #include<cstdio> using namespace std; int mp[105][105], d[105][105]; int order[12], pos[12]; int main() { int t; cin >> t; int kase = 1; while (t--) { int n, m, f; cin >> n >> m >> f; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (i == j)d[i][j] = 0; else d[i][j] = 1e9; for (int i = 1; i <= m; i++) { int u, v, z; cin >> u >> v >> z; d[u][v] = d[v][u] = z; } for (int i = 1; i <= f; i++) { cin >> pos[i]; } for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); for (int i = 1; i <= f; i++)order[i] = i; int ans = 1e9, temp = 0; do { temp = d[1][pos[order[1]]] + d[n][pos[order[f]]]; for (int i = 1; i < f; i++)temp += d[pos[order[i]]][pos[order[i + 1]]]; ans = min(ans, temp); } while (next_permutation(order + 1, order + 1 + f)); printf("Case %d: %d\n", kase++, ans);//cout << ans << endl; } }