1. 程式人生 > >洛谷P1171 售貨員的難題 Tsp問題

洛谷P1171 售貨員的難題 Tsp問題

struct clu 包括 char con tchar namespace () out

洛谷P1171 售貨員的難題

狀壓DP

 1 #include <cstdio> 
 2 #define For(i,j,k) for(int i=j;i<=k;i++)
 3 #define min(a,b) ((a) < (b) ? (a) : (b))
 4 using namespace std ; 
 5 
 6 const int N = 21,inf = 1e8 ; 
 7 int n,mi,all ; 
 8 int dis[N][N];
 9 int dp[N][1<<20] ; 
10 int bin[22] ; 
11 
12 inline int
read() 13 { 14 int x = 0 , f = 1 ; 15 char ch = getchar() ; 16 while(ch<0||ch>9) { if(ch==-) f = -1 ; ch = getchar() ; } 17 while(ch>=0&&ch<=9) { x = x * 10+ch-48 ; ch = getchar() ; } 18 return x * f ; 19 } 20 21 int main() 22 { 23 n = read() ;
24 bin[1] = 1 ; 25 For(i,2,21) bin[ i ] = bin[ i-1 ] * 2 ; 26 all = (1<<n)-1 ; 27 For(i,1,n) 28 For(j,1,n) dis[ i ][ j ] = read() ; 29 For(i,0,n) 30 for(int j=1;j<=all;j+=2) dp[ i ][ j ] = inf ; 31 dp[1][1] = 0 ; 32 for(int zt=3;zt<=all;zt+=2
) 33 For(i,2,n) { 34 if(!(zt&bin[i])) continue ; 35 For(j,1,n) 36 if(zt&bin[j]) dp[i][zt] = min(dp[i][zt],dp[j][zt-bin[i]]+dis[j][i]) ; 37 } 38 mi = inf ; 39 For(i,2,n) 40 if( dp[i][all]+dis[i][1] < mi ) mi = dp[i][all]+dis[i][1] ; 41 printf("%d\n",mi) ; 42 return 0 ; 43 }

搜索

 1 #include<iostream>
 2 #include<cstdio> 
 3 #include<algorithm>
 4 using namespace std;
 5 int n,min1=200010,sum,minv[21],mind=200010;
 6 bool vis[21];
 7 struct node{
 8     int dis,id;
 9 }a[21][21],b[21];
10 void dfs(int q,int last){
11     if(q==n){
12         min1=min(min1,sum+minv[last]);
13         return ;
14     }
15     for(int i=2;i<=n;i++)
16         if(!vis[a[last][i].id]){
17             if(sum+a[last][i].dis>min1)return;//如果當前已走的距離已經大於當前最優值 返回 
18             if(sum+a[last][i].dis+n-q+mind>=min1)return ;
19             //假想最小值剩下的村莊(n-q)的距離都是1 並且最後回到1的時候的距離也是最小的。
20             //如果此時還是超了當前最小值 後面的就都不需要搜了。 
21             vis[a[last][i].id]=1;
22             sum+=a[last][i].dis;
23             dfs(q+1,a[last][i].id);
24             vis[a[last][i].id]=0;
25             sum-=a[last][i].dis;
26         }
27 }
28 bool cmp(node a,node b){
29     return a.dis<b.dis;
30 }
31 int main(){
32     cin>>n;
33     for(int i=1;i<=n;i++){
34         for(int j=1;j<=n;j++){
35             cin>>a[i][j].dis;
36             a[i][j].id=j; 
37         }
38         minv[i]=a[i][1].dis;//minv[i]表示i村莊到1的距離 
39         if(i!=1)mind=min(mind,minv[i]);//表示所有村莊到1的最短距離(不包括1到1) 
40         sort(a[i]+1,a[i]+n+1,cmp);//讀數據時每次得到一行的值後對邊值排序。這樣可以更快得到較優值。 
41     }
42     vis[1]=1;
43     dfs(1,1);
44     cout<<min1;
45     return 0;
46 }

洛谷P1171 售貨員的難題 Tsp問題