zoukankan      html  css  js  c++  java
  • Victor and World(floyed+状压)

     题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418

    题目大意:

    T组测试样例,然后n个点,m条边。每一条边的信息是起点,终点,权值(双向图)。

    然后问你在每个点都至少访问一次的前提下,最终回到1的最少花费。

    具体思路:

    dp[i][j]表示在i的二进制中已经访问的点中最终走到 j 的最小花费。

    我们在dp的时候,假设要求i -> j  ->k, 最好是第一个for循环跑所有的状态,第二个for循环跑i->j,第三个for循环跑j->k。这样能降低复杂度。

    注意这里的Map[u][v]是需要求一个最小值的,我们可以先跑一个floyed预处理出来。或者在dp的时候,把每个点的情况都跑一遍(有点spfa的感觉),这样也能更新出最短距离。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define inf 0x3f3f3f3f
     5 # define ull unsigned long long
     6 const int maxn  = 2e5+100;
     7 const int N = 20;
     8 int Map[N][N];
     9 int dp[maxn][N];
    10 int cal(int t)
    11 {
    12     int ans=0;
    13     for(int i=0; i<=16; i++)
    14     {
    15         if(t&(1<<i))
    16             ans++;
    17     }
    18     return ans;
    19 }
    20 void floyed(int n)
    21 {
    22     for(int i=0; i<n; i++)
    23     {
    24         for(int j=0; j<n; j++)
    25         {
    26             for(int k=0; k<n; k++)
    27             {
    28                 Map[j][k]=min(Map[j][k],Map[j][i]+Map[i][k]);
    29             }
    30         }
    31     }
    32 }
    33 int solve(int n)
    34 {
    35     int maxstate=(1<<n)-1;
    36     for(int i=1; i<=maxstate; i++)
    37     {
    38         //   for(int w=cal(i); w>=0; w--)
    39         //   {
    40         for(int j=0; j<n; j++)
    41         {
    42             if(dp[i][j]==inf)
    43                 continue;
    44             for(int k=0; k<n; k++)
    45             {
    46                 if(Map[j][k]==inf)
    47                     continue;
    48                 dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+Map[j][k]);
    49             }
    50         }
    51     }
    52 //   }
    53     return dp[maxstate][0];
    54 }
    55 
    56 int main()
    57 {
    58     int T;
    59     scanf("%d",&T);
    60     while(T--)
    61     {
    62         memset(Map,inf,sizeof(Map));
    63         memset(dp,inf,sizeof(dp));
    64         int n,m;
    65         scanf("%d %d",&n,&m);
    66         int st,ed,val;
    67         for(int i=1; i<=m; i++)
    68         {
    69             scanf("%d %d %d",&st,&ed,&val);
    70             st--,ed--;
    71             Map[st][ed]=Map[ed][st]=min(Map[st][ed],val);
    72         }
    73         floyed(n);
    74         dp[1][0]=0;
    75         int ans=solve(n);
    76         printf("%d
    ",ans);
    77     }
    78     return 0;
    79 }
    floyed
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define ll long long
     4 # define inf 0x3f3f3f3f
     5 # define ull unsigned long long
     6 const int maxn  = 2e5+100;
     7 const int N = 20;
     8 int Map[N][N];
     9 int dp[maxn][N];
    10 int cal(int t)
    11 {
    12     int ans=0;
    13     for(int i=0; i<=16; i++)
    14     {
    15         if(t&(1<<i))
    16             ans++;
    17     }
    18     return ans;
    19 }
    20 //void floyed(int n)
    21 //{
    22 //    for(int i=0; i<n; i++)
    23 //    {
    24 //        for(int j=0; j<n; j++)
    25 //        {
    26 //            for(int k=0; k<n; k++)
    27 //            {
    28 //                Map[j][k]=min(Map[j][k],Map[j][i]+Map[i][k]);
    29 //            }
    30 //        }
    31 //    }
    32 //}
    33 int solve(int n)
    34 {
    35     int maxstate=(1<<n)-1;
    36     for(int i=1; i<=maxstate; i++)
    37     {
    38         for(int w=cal(i); w>=0; w--)
    39         {
    40         for(int j=0; j<n; j++)
    41         {
    42             if(dp[i][j]==inf)
    43                 continue;
    44             for(int k=0; k<n; k++)
    45             {
    46                 if(Map[j][k]==inf)
    47                     continue;
    48                 dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+Map[j][k]);
    49             }
    50         }
    51         }
    52     }
    53 //   }
    54     return dp[maxstate][0];
    55 }
    56 
    57 int main()
    58 {
    59     int T;
    60     scanf("%d",&T);
    61     while(T--)
    62     {
    63         memset(Map,inf,sizeof(Map));
    64         memset(dp,inf,sizeof(dp));
    65         int n,m;
    66         scanf("%d %d",&n,&m);
    67         int st,ed,val;
    68         for(int i=1; i<=m; i++)
    69         {
    70             scanf("%d %d %d",&st,&ed,&val);
    71             st--,ed--;
    72             Map[st][ed]=Map[ed][st]=min(Map[st][ed],val);
    73         }
    74         //floyed(n);
    75         dp[1][0]=0;
    76         int ans=solve(n);
    77         printf("%d
    ",ans);
    78     }
    79     return 0;
    80 }
    按点更新
  • 相关阅读:
    一个喜欢研究车的80后开车人,自己的经验和感受
    35岁前务必成功的12级跳(男女通用) 转
    如何注册ocx文件
    plsql连接oracle数据库
    float过后 高度无法自适应的解决方法
    Mysql 中文中繁杂的字 插入报错的 解决方案
    power designer 教程
    表单文本框输入时提示文字消失
    diskpart分盘代码
    linux svn 中文 https://my.oschina.net/VASKS/blog/659236
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10900375.html
Copyright © 2011-2022 走看看