【AtCoder Beginner Contest 073 D】joisino's travel

【链接】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;
}


原文地址:https://www.cnblogs.com/AWCXV/p/7626026.html