POJ 3311 Hie with the Pie TSP+Floyd

保证每个点访问过一次就行,然后会到原点。 这种情况可以先做一边floyd,然后跑tsp就好。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <bitset>
#include <list>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <stack>
#include <sstream>
#include <numeric>
#include <fstream>
#include <functional>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 15;
int n,dis[maxn][maxn];
int f[maxn][1 << maxn];

int dfs(int now,int state) {
    if(state == (1 << (n + 1)) - 1) return dis[now][0];
    if(f[now][state] != -1) return f[now][state];
    int ret = INF;
    for(int i = 0;i <= n;i++) if(!(state & (1 << i))) {
        ret = min(ret,dfs(i,state | (1 << i)) + dis[now][i]);
    }
    return f[now][state] = ret;
}

int main() {
    while(scanf("%d",&n),n) {
        memset(f,-1,sizeof(f));
        for(int i = 0;i <= n;i++) {
            for(int j = 0;j <= n;j++) {
                scanf("%d",&dis[i][j]);
            }
        }
        for(int k = 0;k <= n;k++) {
            for(int i = 0;i <= n;i++) {
                for(int j = 0;j <= n;j++) {
                    dis[i][j] = min(dis[i][j],dis[i][k] + dis[k][j]);
                }
            }
        }
        int ret = dfs(0,1);
        printf("%d
",ret);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/rolight/p/3904940.html