poj3311 Hie with the Pie
阿新 • • 發佈:2020-09-14
題目連結:https://vjudge.net/problem/POJ-3311
題意:從0點出發,每個點至少走一次,最後回到0點,求最短長度
相比tsp問題的不同之處是每個點可以走超過一次。這個條件的效果是,假如直接相連的兩點間有一條很長的邊w,可能存在另外一條路,重複走過了某個點,使得兩點距離<w。這樣只要求出兩兩點對之間的最短路即可,由於資料很小,使用floyd,然後就是裸的tsp問題
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int d[15][15],f[15][(1<<15)],n,i,j,k,s,u,v; int main(){ while (cin>>n){ if (n==0) break; n++; memset(d,0x3f,sizeof(d)); memset(f,0x3f,sizeof(f)); for (i=0;i<n;i++) for (j=0;j<n;j++) cin>>d[i][j]; for (k=0;k<n;k++) for (i=0;i<n;i++) for (j=0;j<n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); f[0][1]=0; for (s=0;s<(1<<n);s++) for (v=0;v<n;v++) if (s&(1<<v)){ for (u=0;u<n;u++) if ((u!=v)&&s&(1<<u)) f[v][s]=min(f[v][s],f[u][s^(1<<v)]+d[u][v]); } int ans=1e9; for (i=1;i<n;i++) ans=min(ans,f[i][(1<<n)-1]+d[i][0]); cout<<ans<<endl; } return 0; }