• 「POJ3311」Hie with the Pie


    题目链接 >http://poj.org/problem?id=3311<

    题意:从0出发,经过所有点(点可以重复走)后回到0点,问最短路

    思路分析:

      这题和普通的最短路不太一样,因为题目要求每个点都要走一遍。

      因此我们选择状压。

      用SPFA直接开始做,f[i][status]表示到达点i时,状态为status时的最短路,答案就是f[0][(1<<(n+1))-1]

      更新也和SPFA一模一样

    /*By QiXingzhi*/
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <algorithm>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    using namespace std;
    typedef long long ll;
    const int N = 20;
    const int INF = 1061109567;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar();
        return x * w;
    }
    struct Pizza{
        int u, sta;
    };
    int n;
    int G[N][N],d[N][32768];
    queue <Pizza> q;
    inline void Debug(int status){
        int tmp[30];
        memset(tmp,0,sizeof(tmp));
        int tot = 0;
        while(status > 0){
            tmp[++tot] = status % 2;
            status /= 2;
        }
        for(int i = tot; i > 0; --i){
            printf("%d",tmp[i]);
        }
    }
    inline void SPFA(){
    //    printf("u = %d  status = ",u); Debug(status); printf("   d = %d
    ",d[u][status]);
        memset(d,0x3f,sizeof(d));
        d[0][0] = 0;
        Pizza tmp; tmp.u = 0, tmp.sta = 0;
        q.push(tmp);
        int u,status;
        while(!q.empty()){
            Pizza __t = q.front();
            Pizza __next;
            u = __t.u;
            status = __t.sta;
            q.pop();
            for(int i = 0; i <= n; ++i){
                if(G[u][i] == 0) continue;
                if(d[u][status] + G[u][i] < d[i][status ^ (1 << (i))]){
                    d[i][status ^ (1 << (i))] = d[u][status] + G[u][i];
                    __next.u = i;
                    __next.sta = status ^ (1 << (i));
                    q.push(__next);
                }
            }
        }
        
    }
    int main(){
    //    freopen(".in","r",stdin);
    //    freopen("debug.txt","w",stdout);
        while(1){
            n = r;
            if(n == 0) break;
            for(int i = 0; i <= n; ++i){
                for(int j = 0; j <= n; ++j){
                    G[i][j] = r;
                }
            }
            SPFA();
            printf("%d
    ", d[0][(1<<(n+1))-1]);
        }
        return 0;
    }
  • 相关阅读:
    176. Second Highest Salary
    175. Combine Two Tables
    172. Factorial Trailing Zeroes
    171. Excel Sheet Column Number
    169. Majority Element
    168. Excel Sheet Column Title
    167. Two Sum II
    160. Intersection of Two Linked Lists
    个人博客记录
    <meta>标签
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9334114.html
Copyright © 2020-2023  润新知