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;
}

posted @ 2018-10-20 11:35  俺是小程  阅读(249)  评论(0编辑  收藏  举报