poj 3311 Hie with the Pie (floyd+状态压缩dp~)

来源:互联网 发布:linux虚拟机kvm怎么用 编辑:程序博客网 时间:2024/05/23 15:02

果然还是对状态压缩不同,完全没反应过来用n位二进制表示每个点的经过情况。

.........

#include <cstdio>#include <cstring>#include <iostream>#define Max 15#define INF 0x3f3f3f3fusing namespace std;int dis[Max][Max];int dp[Max][1500];int n;int state;int ans;void Floyd() {    for (int k = 0; k <= n; k++) {        for (int i = 0; i <= n; i++) {            for (int j = 0; j <= n; j++) {                if (dis[i][j] > dis[i][k] + dis[k][j]) {                    dis[i][j] = dis[i][k] + dis[k][j];                }            }        }    }}void resolve() {    for (int state = 0; state < (1 << n); state++) {        for (int i = 1; i <= n; i++) {            if (state & (1 << (i - 1)))  // i城市经过            {                if (state == (1 << (i - 1)))                    dp[i][state] = dis[0][i];  //只经过i                else {                    dp[i][state] = INF;                    for (int j = 1; j <= n; j++) {                        if (j != i && state & (1 << (j - 1))) {                            dp[i][state] =                                min(dp[i][state],                                    dp[j][state ^ (1 << (i - 1))] + dis[j][i]);                        }                    }                }            }        }    }    ans = dp[1][(1 << n) - 1] + dis[1][0];    for (int i = 1; i <= n; i++) {        ans = min(ans, dp[i][(1 << n) - 1] + dis[i][0]);    }    printf("%d\n", ans);}int main(void) {    while (scanf("%d", &n) == 1 && n) {        memset(dis, INF, sizeof(dis));        memset(dp, 0, sizeof(dp));        for (int i = 0; i <= n; i++) {            for (int j = 0; j <= n; j++) {                scanf("%d", &dis[i][j]);            }        }        Floyd();        resolve();    }    return 0;}


阅读全文
0 0
原创粉丝点击