P3044 [USACO12FEB]搬迁Relocation
思路倒是很容易, 最短路 + 状压嘛.
但是debug真的很难受,,,
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> P;
const int MAXN = 1e4 + 10;
inline int read(){
char ch = getchar(); int x = 0;
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return x;
}
struct edge
{
int to, cost;
};vector<edge> g[MAXN];
int N, M, K;
int st[6];
int dis[6][MAXN];
void dijkstra(int s, int po) {
priority_queue<P, vector<P>, greater<P> > q;
memset(dis[po], 0x3f, sizeof(dis[po]));
q.push(P(0, s)), dis[po][s] = 0;
while(!q.empty()) {
P p = q.top(); q.pop();
int u = p.second;
if(dis[po][u] < p.first) continue;
for(int i = 0; i < (int) g[u].size(); i++) {
edge &e = g[u][i];
if(dis[po][u] + e.cost < dis[po][e.to]) {
dis[po][e.to] = dis[po][u] + e.cost;
q.push(P(dis[po][e.to], e.to));
}
}
}
}
int f[(1 << 7)][6];
int main(){
// freopen("p3044.in", "r", stdin);
cin>>N>>M>>K;
for(int i = 1; i <= K; i++) st[i] = read();
for(int i = 1; i <= M; i++) {
int u = read(), v = read(), c = read();
g[u].push_back((edge){v, c}), g[v].push_back((edge){u, c});
}
for(int i = 1; i <= K; i++) dijkstra(st[i], i);
int ans = (1 << 30), d[6][6];
for(int i = 1; i <= N; i++) {
bool flag = false;
for(int j = 1; j <= K; j++) flag |= (st[j] == i);
if(flag) continue;
d[0][0] = 0;
for(int j = 1; j <= K; j++)
for(int k = j; k <= K; k++)
d[j][k] = d[k][j] = dis[j][st[k]];
for(int j = 1; j <= K; j++) d[0][j] = d[j][0] = dis[j][i];
memset(f, 0x3f, sizeof(f)); f[1][0] = 0;
for(int state = 1; state < (1 << (K + 1)); state++)
for(int p = 0; p <= K; p++) if(state & (1 << p)) {
for(int k = 0; k <= K; k++)
f[state | (1 << k)][k] = min(f[state | (1 << k)][k], f[state][p] + d[p][k]);
}
ans = min(ans, f[(1 << (K + 1)) - 1][0]);
}
printf("%d\n", ans);
return 0;
}