• [状压dp]HDU3001 Travelling


    题意: 走n个城市, m条路, 起点任意, 每个城市走不超过两次, 求最小花费, 不能走输出-1.

    $1le nle 10$

    分析: 每个城市的拜访次数为0 1 2, 所以三进制状压, 先预处理10位(n最大为10)的三进制数

     1 int num[12], vis[60005][12];
     2 
     3 void init()
     4 {
     5     num[0]=1;
     6     for(int i=1; i<=10; i++)
     7         num[i]=num[i-1]*3;
     8     memset(vis, -1, sizeof(vis));
     9     for(int i=0; i<=num[10]; i++)
    10     {
    11         int x=i;
    12         for(int j=0; j<=10; j++)
    13         {
    14             vis[i][j]=x%3;
    15             x/=3;
    16         }
    17     }
    18 }
      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <climits>
      5 #include <cctype>
      6 #include <cmath>
      7 #include <string>
      8 #include <sstream>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <iomanip>
     12 using namespace std;
     13 #include <queue>
     14 #include <stack>
     15 #include <vector>
     16 #include <deque>
     17 #include <set>
     18 #include <map>
     19 typedef long long LL;
     20 typedef long double LD;
     21 #define pi acos(-1.0)
     22 #define lson l, m, rt<<1
     23 #define rson m+1, r, rt<<1|1
     24 typedef pair<int, int> PI;
     25 typedef pair<int, PI> PP;
     26 #ifdef _WIN32
     27 #define LLD "%I64d"
     28 #else
     29 #define LLD "%lld"
     30 #endif
     31 //#pragma comment(linker, "/STACK:1024000000,1024000000")
     32 //LL quick(LL a, LL b){LL ans=1;while(b){if(b & 1)ans*=a;a=a*a;b>>=1;}return ans;}
     33 //inline int read(){char ch=' ';int ans=0;while(ch<'0' || ch>'9')ch=getchar();while(ch<='9' && ch>='0'){ans=ans*10+ch-'0';ch=getchar();}return ans;}
     34 //inline void print(LL x){printf(LLD, x);puts("");}
     35 //inline void read(int &x){char c = getchar();while(c < '0') c = getchar();x = c - '0'; c = getchar();while(c >= '0'){x = x * 10 + (c - '0'); c = getchar();}}
     36 
     37 #define INF 2139062143
     38 int dp[60005][12];
     39 int mp[12][12];
     40 int num[12], vis[60005][12];
     41 void init()
     42 {
     43     num[0]=1;
     44     for(int i=1; i<=10; i++)
     45         num[i]=num[i-1]*3;
     46     memset(vis, -1, sizeof(vis));
     47     for(int i=0; i<=num[10]; i++)
     48     {
     49         int x=i;
     50         for(int j=0; j<=10; j++)
     51         {
     52             vis[i][j]=x%3;
     53             x/=3;
     54         }
     55     }
     56 }
     57 int main()
     58 {
     59 #ifndef ONLINE_JUDGE
     60     freopen("in.txt", "r", stdin);
     61     freopen("out.txt", "w", stdout);
     62 #endif
     63     init();
     64     int n, m;
     65     while(~scanf("%d%d", &n, &m))
     66     {
     67         memset(dp, 127, sizeof(dp));
     68         memset(mp, 127, sizeof(mp));
     69         for(int i=0; i<n; i++)
     70             dp[num[i]][i]=0;
     71         while(m--)
     72         {
     73             int a, b, c;
     74             scanf("%d%d%d", &a, &b, &c);
     75             mp[a-1][b-1]=mp[b-1][a-1]=min(mp[a-1][b-1], c);
     76         }
     77         int ans=INF;
     78         for(int i=0;i<num[n];i++) // n个城市走过次数的状态i
     79         {
     80             bool flag=0;
     81             for(int j=0;j<n;j++)   // 当前在j
     82             {
     83                 if(!vis[i][j])
     84                     flag=1;
     85                 if(dp[i][j]==INF)
     86                     continue;
     87                 for(int k=0;k<n;k++)   // 走去 k
     88                     if(j!=k)
     89                     {
     90                         if(vis[i][k]>=2)
     91                             continue;
     92                         if(mp[j][k]==INF)
     93                             continue;
     94                         dp[i+num[k]][k]=min(dp[i+num[k]][k], dp[i][j]+mp[j][k]);
     95                     }
     96             }
     97             if(!flag)
     98                 for(int j=0;j<n;j++)
     99                     ans=min(ans, dp[i][j]);
    100         }
    101         if(ans==INF)
    102             printf("-1
    ");
    103         else
    104             printf("%d
    ", ans);
    105     }
    106     return 0;
    107 }
    HDOJ3001
  • 相关阅读:
    javascript 写一个随机范围整数的思路
    Promise中的next 另一个用法
    继上一篇随笔,优化3张以上图片轮播React组件
    低性能3张图片轮播React组件
    用函数式编程思维解析anagrams函数
    Python time time()方法
    torch.view().expand()
    pytorch中的top_K()函数
    设定学习率衰减
    两个集合求交集
  • 原文地址:https://www.cnblogs.com/Empress/p/4039265.html
Copyright © 2020-2023  润新知