zoukankan      html  css  js  c++  java
  • Travelling(hdu3001)

    Travelling

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 5762    Accepted Submission(s): 1857


    Problem Description
    After coding so many days,Mr Acmer wants to have a good rest.So travelling is the best choice!He has decided to visit n cities(he insists on seeing all the cities!And he does not mind which city being his start station because superman can bring him to any city at first but only once.), and of course there are m roads here,following a fee as usual.But Mr Acmer gets bored so easily that he doesn't want to visit a city more than twice!And he is so mean that he wants to minimize the total fee!He is lazy you see.So he turns to you for help.
     
    Input
    There are several test cases,the first line is two intergers n(1<=n<=10) and m,which means he needs to visit n cities and there are m roads he can choose,then m lines follow,each line will include three intergers a,b and c(1<=a,b<=n),means there is a road between a and b and the cost is of course c.Input to the End Of File.
     
    Output
    Output the minimum fee that he should pay,or -1 if he can't find such a route.
     
    Sample Input
    2 1
    1 2 100
    3 2
    1 2 40
    2 3 50
    3 3
    1 2 3
    1 3 4
    2 3 10

    Sample Output

    100
    90
    7
    题意:有N个城市,一个人要 经过每个点,且经过每个点不超过2次。求最少的路费。可以从任意一个点开始。
    思路:TSP,这个是三进制的状态压缩,因为过每个点要求不超过两次,其余dp的思路和TSP二进制差不多,可以说一样。
    dp[i][j]表示在状态i下以j点结束的所要的最小费用。 dp[i][j]=min(dp[i][j],dp[cc][v]+ma[v][j]);cc,表示i的上一个状态。
    代码:
      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<string.h>
      4 #include<iostream>
      5 #include<stdlib.h>
      6 #include<queue>
      7 #include<stack>
      8 typedef long long ll;
      9 long long  ma[20][20];
     10 long long dp[60000][20];//开pow(3,11);
     11 long long san[60000][20];
     12 int a[60000];//记录状态是否都至少经过一次
     13 const long long N=1e9;
     14 using  namespace std;
     15 int main(void)
     16 {
     17     long long  n,i,j,k,p,q;
     18     long long  x,y,v;
     19     memset(san,0,sizeof(san));
     20     for(i=0; i<60000; i++)
     21     {
     22         ll vv=i;
     23         int flag=0;
     24         int f=0;
     25         while(vv)
     26         {
     27             san[i][f++]=vv%3;
     28             if(vv%3==0)
     29             {
     30                 flag=1;
     31             }
     32             vv/=3;
     33 
     34         }
     35         if(flag==0) a[i]=1;
     36     }//把状态用三进制表示
     37     while(scanf("%lld %lld",&p,&q)!=EOF)
     38     {
     39         for(i=0; i<20; i++)
     40             for(j=0; j<20; j++)
     41                 ma[i][j]=N;
     42         for(i=0; i<60000; i++)
     43             for(j=0; j<20; j++)
     44                 dp[i][j]=N;
     45         for(i=0; i<q; i++)
     46         {
     47             scanf("%lld %lld %lld",&x,&y,&k);
     48             ma[x-1][y-1]=min(k,ma[x-1][y-1]);
     49             ma[y-1][x-1]=min(k,ma[x-1][y-1]);
     50         }
     51         int xx=1;
     52         for(i=0; i<p; i++)
     53         {
     54             dp[xx][i]=0;
     55             xx*=3;
     56         }//出发点初始化置0。
     57         int yy=1;
     58         for(i=0; i<p; i++)
     59         {
     60             yy*=3;
     61         }
     62         for(i=1; i<yy; i++)
     63         {
     64             ll pp=i;
     65             for(j=0; j<p; j++)
     66             {
     67                 if(san[pp][j]>0)//判断当前状态是否经过这点
     68                 {
     69                     int uu=0;
     70                     int rr=1;
     71                     for(v=0; v<p; v++)
     72                     {
     73                         int vp=san[pp][v];
     74                         if(v==j)
     75                         {
     76                             vp--;
     77                         }
     78                         vp*=rr;
     79                         rr*=3;
     80                         uu+=vp;
     81                     }
     82                     for(v=0; v<p; v++)
     83                     {
     84                         if(san[uu][v]>0)//判断上个状态是否经过上个状态的结束点
     85                         {
     86                             dp[i][j]=min(dp[i][j],dp[uu][v]+ma[v][j]);
     87 
     88                         }
     89                     }
     90                 }
     91             }
     92 
     93         }
     94         long long minn=N;
     95         int tu=0;
     96         for(i=0; i<p; i++)
     97         {
     98             tu*=3;
     99             tu+=1;
    100         }
    101         for(i=tu; i<yy; i++)//至少经过每个点一次中取最小
    102         {
    103             if(a[i])
    104             {
    105                 for(j=0; j<p; j++)
    106                 {
    107                     if(dp[i][j]<minn)
    108                     {
    109                         minn=dp[i][j];
    110                     }
    111 
    112                 }
    113             }
    114 
    115         }
    116 
    117         if(minn==N)
    118         {
    119             printf("-1
    ");
    120         }
    121         else
    122             printf("%lld
    ",minn);
    123     }
    124     return 0;
    125 }
    View Code
    油!油!you@
  • 相关阅读:
    Nginx 配置指令的执行顺序(一)
    缘起 --转
    Nginx 变量漫谈(八)
    Nginx 变量漫谈(七)
    Nginx 变量漫谈(六)
    Windows批量添加防火墙例外端口
    Neo4j 的一些使用心得
    一文教你用 Neo4j 快速构建明星关系图谱
    GemFire 入门篇1:GemFire 是什么?
    数据结构(逻辑结构,物理结构,特点)
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5168927.html
Copyright © 2011-2022 走看看