• HDU 4284 Travel [TSP]


      给出N个城市,城市之间的路径需要一定的花费。其中一些城市(H<=15)是必达的,在这些城市可以打工赚钱,但前提是有足够的钱购买这些城市的工作许可。问是否能获得所有的许可并且最终回到起点。 

      这题和我之前出过的一个题很像。。http://acm.csu.edu.cn/onlinejudge/problem.php?id=1175

      先对这H个点做一遍最短路,这题的点比较少,直接用FLOYD,然后对这H个点用哈密顿回路DP就可以了。

      需要注意的是一个城市允许经过多次,如果第一次来这个城市时不够钱购买工作许可可以在其他城市工作赚了钱之后再回来拿。。。

      

     1 #include <string.h>
     2 #include <stdio.h>
     3 #include <algorithm>
     4 #include <queue>
     5 #define MAXE 10005
     6 #define MAXN 205
     7 #define INF 0x3f3f3f3f
     8 #define rep(i,a,n) for(int i=a;i<=n;i++)
     9 using namespace std;
    10 int cas,n,m,money,cts;
    11 int tu,tv,tw;
    12 int map[20][20],mapb[105][105];
    13 int ci[20],di[20],id[20],cits,full;
    14 int dp[70000][17];
    15 int main(){
    16     //freopen("test.in","r",stdin);
    17     scanf("%d",&cas);
    18     while(cas--){
    19         scanf("%d%d%d",&n,&m,&money);
    20         rep(i,1,n)rep(j,1,n)mapb[i][j]=(i==j?0:INF);
    21         rep(i,1,m){
    22             scanf("%d%d%d",&tu,&tv,&tw);
    23             mapb[tu][tv]=mapb[tv][tu]=std::min(mapb[tu][tv],tw);
    24         }
    25         //FLOYD
    26         rep(k,1,n)rep(i,1,n)rep(j,1,n)
    27             mapb[i][j]=std::min(mapb[i][j],mapb[i][k]+mapb[k][j]);
    28         scanf("%d",&cts);cts--;
    29         //put the city 1 to the last position
    30         rep(i,0,cts)scanf("%d%d%d",&id[i],&ci[i],&di[i]);
    31         id[++cts]=1,ci[cts]=di[cts]=0;
    32         //init the chosen city map
    33         rep(i,0,cts)rep(j,0,cts)map[i][j]=mapb[id[i]][id[j]];
    34         full=(1<<(cts+1))-1;
    35         //Hamilton
    36         rep(s,0,full)rep(i,0,cts)dp[s][i]=-INF;
    37         dp[0][cts]=money;
    38         rep(s,0,full)rep(i,0,cts)if(dp[s][i]!=-INF){
    39             rep(j,0,cts)if((s>>j&1)==0&&dp[s][i]>=map[i][j]){
    40                 int nmax=dp[s][i]-map[i][j]-di[j];
    41                 if(nmax<0)continue;
    42                 if(nmax+ci[j]>dp[s|1<<j][j])dp[s|1<<j][j]=nmax+ci[j];
    43             }
    44         }
    45         int ans=-1;
    46         rep(i,0,cts)ans=std::max(ans,dp[full][i]);
    47         printf(dp[full][cts]>=0?"YES\n":"NO\n");
    48     }
    49 }
  • 相关阅读:
    【ZOJ2112】【整体二分+树状数组】带修改区间第k大
    【POJ2104】【整体二分+树状数组】区间第k大
    【清澄A1333】【整体二分+二维树状数组】矩阵乘法(梁盾)
    【BZOJ2752】【线段树】高速公路
    【POJ2886】【线段树】Who Gets the Most Candies?
    【POJ2482】【线段树】Stars in Your Window
    【HDU4348】【主席树】To the moon
    JDBC
    java异常
    JavaScript对象
  • 原文地址:https://www.cnblogs.com/swm8023/p/2684618.html
Copyright © 2020-2023  润新知