保证每个点访问过一次就行,然后会到原点。 这种情况可以先做一边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; }