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@
  • 相关阅读:
    ParallelStreamAPI
    VS Code 安装后的一些配置项
    RSA算法在Python Django中的简单应用
    DLL重定向处理
    Oracle和MySQL差异总结
    Oracle中Table函数简单应用实例
    数据库开发规范
    CentOS7安装开发工具套件时报错解决方案
    安装beanstalkd队列问题——No package beanstalkd available
    CentOS7配置yum源
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5168927.html
Copyright © 2011-2022 走看看