標籤:style blog color os io for 2014 代碼
經典TSP變形
學到:1、floyd O(n^3)處理任意兩點的最短路
2、集合的位表示,我會在最後的總結出寫出。注意寫代碼之前一定設計好位的狀態,本題中,第0位到第n位分別代表第i個城市,1是已經走過,0沒走過
那麼DP方程 :dp[s][i]--當前在城市i,狀態為s(s儲存的是走過了那些城市)
3、最後要求形成迴路,那麼就是min(dp[1<<(n+1)-1][i],dp[0][i])
#include <cstdio>#include <cstring>#include <algorithm>#include <string>#include <iostream>#include <cmath>#include <map>#include <queue>using namespace std;#define ls(rt) rt*2#define rs(rt) rt*2+1#define ll long long#define rep(i,s,e) for(int i=s;i<e;i++)#define repe(i,s,e) for(int i=s;i<=e;i++)#define CL(a,b) memset(a,b,sizeof(a))#define IN(s) freopen(s,"r",stdin)const int MAXN = 12;int dis[MAXN][MAXN];int dp[1<<MAXN][MAXN];const int INF = 1e9+10;int n;void floyd(){ rep(k,0,n+1) rep(i,0,n+1) rep(j,0,n+1) dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);}int main(){ //IN("poj3311.txt"); int len; while(~scanf("%d",&n) && n) { rep(i,0,n+1) rep(j,0,n+1) dp[i][j]=dis[i][j]=INF; rep(i,0,n+1) rep(j,0,n+1) { scanf("%d",&len); dis[i][j]=min(dis[i][j],len); } floyd();//求出任意兩點的距離 int S=1<<(n+1); rep(i,0,S) rep(j,0,n+1) { dp[i][j]=INF; } for(int s=0;s<S;s++)//枚舉所有的狀態 rep(i,0,n+1) { if(s&(1<<(i))) { if(s==(1<<i))dp[s][i]=dis[0][i]; else rep(j,0,n+1) if(s&(1<<j) && i!=j) { dp[s][i]=min(dp[s^(1<<i)][j]+dis[j][i],dp[s][i]); } } } int ans=INF; for(int i=0;i<n+1;i++) ans=min(ans,dp[(S-1)][i]+dis[i][0]); printf("%d\n",ans); } return 0;}