zoukankan      html  css  js  c++  java
  • Travelling (三进制+状压dp)

    题目链接

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 inline ll read(){
     5     int x=0,f=1;char ch=getchar();
     6     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     7     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     8     return x*f;
     9 }
    10 
    11 /***********************************************************/
    12 
    13 int n, m;     // n < = 10
    14 const int maxn = 6e4+5;
    15 int d[12][maxn];
    16 //用三进制形式来表示状态
    17 int dist[15][15];
    18 //表示路径
    19 int t[12];
    20 int cnt, state[maxn];
    21 int temp;
    22 
    23 //判断S的三进制是否没有一个0
    24 bool legal(int S){
    25     bool ok = true;
    26     for(int i = 0;i <= n-1;i++){
    27         if(S%3 == 0){
    28             ok = false;
    29             break;
    30         }
    31         S /= 3;
    32     }
    33     return ok;
    34 }
    35 
    36 void init(){
    37     temp = 1;
    38     for(int i = 0;i <= 10;i++){
    39         t[i] = temp;
    40         temp *= 3;
    41     }
    42 }
    43 
    44 //i点在集合S中是否出现了至少一次
    45 inline bool in(int i, int S){
    46     for(int j = 0;j < i;j++)
    47         S /= 3;
    48     if(S%3) return true;
    49     else return false;
    50 }
    51 
    52 int dp(int i, int S){
    53     if(d[i][S] >= 0) return d[i][S];
    54     int &ans = d[i][S];
    55     ans = 1e9;
    56     int S1 = S - t[i];
    57     for(int j = 0;j < n;j++){
    58         if(j != i && in(j, S1) && dist[j][i] != -1)
    59             ans = min(ans, dp(j, S1) + dist[j][i]);
    60     }
    61     return ans;
    62 }
    63 
    64 int main(){
    65     init();
    66     while(~scanf("%d %d", &n, &m)){
    67         int max_3 = 0;
    68         for(int i = 0;i < n;i++)
    69             max_3 += t[i];
    70         cnt = 0;
    71         for(int S = max_3;S < t[n];S++){
    72             if(legal(S))
    73                 state[cnt++] = S;
    74         }
    75         memset(dist, -1, sizeof(dist));
    76         for(int i = 0;i < m;i++){
    77             int a, b, c;
    78             scanf("%d%d%d", &a, &b, &c);
    79             a--;b--;
    80             //更新长度
    81             if(dist[a][b] == -1 || dist[a][b] > c)
    82                 dist[a][b] = dist[b][a] = c;
    83         }
    84         memset(d, -1, sizeof(d));
    85         for(int i = 0;i < n;i++)
    86             d[i][t[i]] = 0;
    87 
    88         int sum = dp(0, max_3);
    89         for(int i = 0;i < n;i++){
    90             for(int j = 0;j < cnt;j++){
    91                 sum = min(sum, dp(i, state[j]));
    92             }
    93         }
    94         if(sum == 1e9) printf("-1
    ");
    95         else printf("%d
    ", sum);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    烂泥:jira7.2安装、中文及破解
    烂泥:VMWare Workation双网卡配置IP地址
    烂泥:centos6 yum方式升级内核
    烂泥:python2.7和python3.5源码安装
    烂泥:zabbix3.0安装与配置
    烂泥:利用awstats分析nginx日志
    烂泥:切割nginx日志
    JavaScript之函数
    Django之根据已经存在数据库中的表自动生成模型
    Django之操作数据库
  • 原文地址:https://www.cnblogs.com/ouyang_wsgwz/p/9823539.html
Copyright © 2011-2022 走看看