• 洛谷P1171 售货员的难题 Tsp问题


    洛谷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
    ",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 }
  • 相关阅读:
    小埋的Dancing Line之旅:比赛题解&热身题题解
    洛谷P1311 选择客栈
    洛谷 P1039 侦探推理
    洛谷P1140 相似基因
    反⑨baka拖更大队:临时约法
    随机数据生成器
    洛谷P2285 【[HNOI2004]打鼹鼠】
    洛谷P3958 奶酪
    YII 关联查询
    Filter
  • 原文地址:https://www.cnblogs.com/third2333/p/7620553.html
Copyright © 2020-2023  润新知