zoukankan      html  css  js  c++  java
  • POJ 3311 Hie with the Pie (BFS+最短路+状态压缩)

    题意:类似于TSP问题,只是每个点可以走多次,求回到起点的最短距离(起点为点0)。

    分析:状态压缩,先预处理各点之间的最短路,然后sum【i】【buff】表示在i点,状态为buff时所耗时。。。。。。。

    所以把10 * 1024 种状态来一遍,取sum【0】【(1<<n)-1】的最小值

    只是把状态压缩DP改成bfs+状态压缩了


    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #define INF 0x7FFFFFFF
    using namespace std;
    
    int dist[11][11],sum[11][1 << 10];
    struct node {
        int x,buff;
    } q[55555];
    int head,tail,n,ans;
    
    void floyd() {
        for(int i=0; i<=n; i++) {
            for(int j=0; j<=n; j++) {
                for(int k=0; k<=n; k++) {
                    if(dist[j][i] + dist[i][k] < dist[j][k]) dist[j][k] = dist[j][i] + dist[i][k];
                }
            }
        }
    }
    
    void bfs() {
        ans = INF;
        memset(sum,0,sizeof(sum));
        head = 0;
        tail = 0;
        q[head].x = 0;
        q[head++].buff = 0;
        while(head != tail) {
            node t = q[tail ++];
            node tt;
            if(t.x == 0 && t.buff == (1 << n) - 1) {
                ans = min(ans,sum[t.x][t.buff]);
            }
            for(int i=0; i<=n; i++) {
                if(t.x == i) continue;
                if(i != 0) {  
                    if(t.buff & (1 << (i-1))) tt.buff = t.buff;
                    else tt.buff = t.buff + (1 << (i-1));
                } else tt.buff = t.buff;
                //如果该点该状态已经访问过,而这次如果没有更优解,则剪了
                if(sum[i][tt.buff] != 0 && sum[i][tt.buff] > sum[t.x][t.buff] + dist[t.x][i]) {
                    sum[i][tt.buff] = sum[t.x][t.buff] + dist[t.x][i];
                    tt.x = i;
                    q[head++] = tt;
                //未访问则老样子
                } else if(sum[i][tt.buff] == 0) {
                    sum[i][tt.buff] = sum[t.x][t.buff] + dist[t.x][i];
                    tt.x = i;
                    q[head ++] = tt;
                }
            }
        }
    }
    int main() {
        while(scanf("%d",&n) && n) {
            for(int i=0; i<=n; i++)
                for(int j=0; j<=n; j++) {
                    scanf("%d",&dist[i][j]);
                }
            floyd();
            bfs();
            printf("%d
    ",ans);
        }
        return 0;
    }


  • 相关阅读:
    Ext架构分析(6)最简单的layout:AnchorLayout
    Ext架构分析(4)Container之旅
    ext学习资源汇总
    DomQuery v1.1 高级
    Ext 2.0 教程 目录
    HDOJ2006 ( 求奇数的乘积 ) 【水题】
    HDOJ2017 ( 字符串统计 ) 【水题】
    状态模式(State)
    HDOJ2002 ( 计算球体积 ) 【水题】
    HDOJ2007 ( 平方和与立方和 ) 【水题】
  • 原文地址:https://www.cnblogs.com/pangblog/p/3278449.html
Copyright © 2011-2022 走看看