状压 dp

最短哈密尔顿路径

P4802 [CCO 2015]路短最

#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
int n, m, w[19][19], f[1 << 19][19];
int main(){
    scanf("%d %d", &n, &m);
    for (int i = 1, s, d, l; i <= m; ++i) {
        scanf("%d %d %d", &s, &d, &l);
        w[s][d] = l;
    }
    memset(f, 0x8f, sizeof f);// 要够小?
    f[1][0] = 0;
    for (int i = 1; i < 1 << n; ++i)// 枚举所有状态
        for (int j = 0; j < n; ++j)// 枚举当前到的点
            if (i >> j & 1) 
                for (int k = 0; k < n; ++k)// 枚举由哪个点转移过来
                    if ((i ^ 1 << j) >> k & 1 && w[k][j])// 边要存在
                       f[i][j] = max(f[i][j], f[i ^ 1 << j][k] + w[k][j]); 
    int ans = 0;
    for (int i = 1; i < 1 << n; ++i) ans = max(ans, f[i][n - 1]);
    // 不一定要把 n 个城市都走完 所以要在所有以 n - 1 为最后一个点的状态里得出答案
    // 枚举所有的 s , 找到所有情况保证正确性
    printf("%d\n", ans);
    return 0;
}
posted @ 2021-10-14 16:16  牛蛙丶丶  阅读(19)  评论(0编辑  收藏  举报