zoukankan      html  css  js  c++  java
  • 【CODEVS】2800 送外卖

    【算法】最短路(floyd)+状态压缩型动态规划

    【题解】

    经典的TSP问题(货郎担问题):求最小权哈密顿回路(遍历全图点一次且仅一次)。本题稍作改动,先说原TSP问题解法:状压DP。

    状态用二进制表示每个点是否走过(状态也包括最后走的点),状态转移关键在于每个点都有且只有另一个点指向它,所以先可以枚举状态k(按顺序枚举时,后面集合的子集已经全部计算完毕),

    对于每个状态枚举最后到达的节点i,再枚举i的所有邻边节点j,从恰好缺i且最后节点为j的状态转移过来。

    memset(f,0x3f,sizeof(f));//初始化为正无穷 
    f[1][0]=0;//不算起点 
    for(int k=1;k<=(1<<n)-1;k++)
     for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
       if((1<<(i-1))&k)f[i][k]=min(f[i][k],f[j][k-(1<<(i-1))]+mp[j][i]);
    printf("%d",f[1][(1<<n)-1]);
    View Code

    这里有一个细节,设初始状态为f[1][0]=0(起点为1),即起点的初态不包含自身,那么最后f[1][(1<<n)-1]就是答案。

    那么这道题的修改主要是一个城市可以经过多次,那么先跑一遍floyd得出两城市间最短距离后就不必再纠结重复经过的事了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=20;
    int n,mp[maxn][maxn],f[maxn][70010];
    int main()
    {
        scanf("%d",&n);n++;
        int x;
        for(int i=1;i<=n;i++)
         {
             for(int j=1;j<=n;j++)
              {
                  scanf("%d",&x);
                  mp[i][j]=x;
              }
         }
        for(int i=1;i<=n;i++)mp[i][i]=0;
        for(int k=1;k<=n;k++)
         for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
           mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
        memset(f,0x3f,sizeof(f));
        f[1][0]=0;
        for(int k=1;k<=(1<<n)-1;k++)
         for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
           if((1<<(i-1))&k)f[i][k]=min(f[i][k],f[j][k-(1<<(i-1))]+mp[j][i]);
        printf("%d",f[1][(1<<n)-1]);
        return 0;
    }
    View Code
  • 相关阅读:
    android之wifi开发
    android wifi讲解 wifi列表显示
    jQuery格式化时间插件formatDate
    Android自定义照相机实现(拍照、保存到SD卡,利用Bundle在Acitivity交换数据)
    Android圆形图片自定义控件
    Android自定义控件
    SQL表连接查询(inner join、full join、left join、right join)
    Jquery 中each循环嵌套的使用示例教程
    JQuery遍历json数组的3种方法
    怎样从数据库层面检測两表内容的一致性
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6505203.html
Copyright © 2011-2022 走看看