zoukankan      html  css  js  c++  java
  • poj 3311 floyd+dfs或状态压缩dp 两种方法

    Hie with the Pie
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 6436   Accepted: 3470

    Description

    The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be processed before he starts any deliveries. Needless to say, he would like to take the shortest route in delivering these goodies and returning to the pizzeria, even if it means passing the same location(s) or the pizzeria more than once on the way. He has commissioned you to write a program to help him.

    Input

    Input will consist of multiple test cases. The first line will contain a single integer n indicating the number of orders to deliver, where 1 ≤ n ≤ 10. After this will be n + 1 lines each containing n + 1 integers indicating the times to travel between the pizzeria (numbered 0) and the n locations (numbers 1 to n). The jth value on the ith line indicates the time to go directly from location i to location j without visiting any other locations along the way. Note that there may be quicker ways to go from i to j via other locations, due to different speed limits, traffic lights, etc. Also, the time values may not be symmetric, i.e., the time to go directly from location i toj may not be the same as the time to go directly from location j to i. An input value of n = 0 will terminate input.

    Output

    For each test case, you should output a single number indicating the minimum time to deliver all of the pizzas and return to the pizzeria.

    Sample Input

    3
    0 1 10 10
    1 0 1 2
    10 1 0 10
    10 2 10 0
    0

    Sample Output

    8

    Source

     
    题意:有N个城市(1~N)和一个PIZZA店(0),要求一条回路,从0出发,又回到0,而且距离最短。
     求距离之和。
     
    题解:n的范围很小,先floyd 求出每两点之间的最短距离
        一遍dfs求 能够构成回路的距离最小值
     
    简单dfs处理
     1 /******************************
     2 code by drizzle
     3 blog: www.cnblogs.com/hsd-/
     4 ^ ^    ^ ^
     5  O      O
     6 ******************************/
     7 //#include<bits/stdc++.h>
     8 #include<iostream>
     9 #include<cstring>
    10 #include<cmath>
    11 #include<cstdio>
    12 #define ll long long
    13 #define mod 1000000007
    14 #define PI acos(-1.0)
    15 using namespace std;
    16 int n;
    17 ll mp[15][15];
    18 int used[15];
    19 ll ans=mod;
    20 void floyd()
    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             mp[j][k]=min(mp[j][k],mp[j][i]+mp[i][k]);
    29             }
    30         }
    31     }
    32 }
    33 void dfs(int dep,int v,ll c)
    34 {
    35     if(dep==n)
    36     {
    37      ans=min(ans,c+mp[v][0]);
    38      return ;
    39     }
    40     for(int i=1;i<=n;i++)
    41     {
    42         if(!used[i])
    43         {
    44             used[i]=1;
    45             dfs(dep+1,i,c+mp[v][i]);
    46             used[i]=0;
    47         }
    48     }
    49 }
    50 int main()
    51 {
    52     while((scanf("%d",&n))!=EOF){
    53         ans=mod;
    54         if(n==0) break;
    55         memset(mp,0,sizeof(mp));
    56         memset(used,0,sizeof(used));
    57         for(int i=0;i<=n;i++)
    58             for(int j=0;j<=n;j++)
    59                 scanf("%I64d",&mp[i][j]);
    60         used[0]=1;
    61         floyd();
    62         dfs(0,0,0);
    63         printf("%I64d
    ",ans);
    64     }
    65     return 0;
    66 }
    状态压缩dp处理   也是第一次接触状态压缩 算是入门了 参考别人的代码 码的。
    dfs处理 会有很多重复的运算 考虑dp处理其实就是类似poj滑雪的记忆化
    dp[i][j]  代表 状态i下到j城市的最短距离   ans=dp[i][j]+mp[j][0]//回到0点
    这里重要处理的就是怎么存储一个状态 共有2^10种
    采用状态压缩 对于城市的去或者不去 采用0/1标记 
    1~2^10 每一个值代表一个状态  具体看fun()
     1 /******************************
     2 code by drizzle
     3 blog: www.cnblogs.com/hsd-/
     4 ^ ^    ^ ^
     5  O      O
     6 ******************************/
     7 //#include<bits/stdc++.h>
     8 #include<iostream>
     9 #include<cstring>
    10 #include<cmath>
    11 #include<cstdio>
    12 #define ll long long
    13 #define mod 1000000007
    14 #define PI acos(-1.0)
    15 using namespace std;
    16 int n;
    17 ll mp[15][15];
    18 ll dp[1<<11][15];
    19 int used[15];
    20 ll ans=mod;
    21 void floyd()
    22 {
    23     for(int i=0;i<=n;i++)
    24     {
    25         for(int j=0;j<=n;j++)
    26         {
    27             for(int k=0;k<=n;k++)
    28             {
    29             mp[j][k]=min(mp[j][k],mp[j][i]+mp[i][k]);
    30             }
    31         }
    32     }
    33 }
    34 void fun()
    35 {
    36     for(int s=0;s<=(1<<n)-1;s++)
    37         for(int i=1;i<=n;i++)
    38     {
    39         if(s&(1<<(i-1)))//判断是否经过城市i
    40         {
    41             if(s==(1<<(i-1)))//只经过i
    42             dp[s][i]=mp[0][i];
    43             else
    44             {
    45                 dp[s][i]=mod;
    46                 for(int j=1;j<=n;j++)
    47                 {
    48                     if((s&(1<<(j-1)))&&j!=i)//判断绕行其他城市是否更优,取最优
    49                      dp[s][i]=min(dp[s^(1<<(i-1))][j]+mp[j][i],dp[s][i]);
    50                 }//类似floyd的处理
    51             }
    52         }
    53     }
    54     ans=dp[(1<<n)-1][1]+mp[1][0];//回到0点
    55     for(int i=1;i<=n;i++)
    56         ans=min(ans,dp[(1<<n)-1][i]+mp[i][0]);
    57     printf("%I64d
    ",ans);
    58 }
    59 int main()
    60 {
    61     while((scanf("%d",&n))!=EOF){
    62         ans=mod;
    63         if(n==0) break;
    64         memset(mp,0,sizeof(mp));
    65         memset(used,0,sizeof(used));
    66         for(int i=0;i<=n;i++)
    67             for(int j=0;j<=n;j++)
    68                 scanf("%I64d",&mp[i][j]);
    69         floyd();
    70         fun();
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    android高级UI之Paint Xfermode
    android高级UI之Paint滤镜
    常见文献管理软件
    linux下10款markdown软件
    markdown页面内跳转
    Ubuntu18.04配制阿里巴巴的源
    python中TAB补全
    word中手动添加endnote的加载项
    MarkDown添加图片的三种方式
    word前页与后页页码断开
  • 原文地址:https://www.cnblogs.com/hsd-/p/5712895.html
Copyright © 2011-2022 走看看