HDU 4284 Travel

/*摘自网络

因为必须经过H个点,H<=15,安排一个顺序使得能遍历完H个城市,可以用状态DP做。

用Floyd求任意两点之间的最短距离,也就是最小路费。

状态DP求经过某些城市集合s,最后到达某个城市i获得的最大收益,用f[s][i]表示。

最后要回到起始点1,这样判断是否能从f[all][i]状态是否能回到1点即可,all是所有的必经点。


PS:比赛的时候不是这么想,比赛时是把回到起始点1虚拟成n+1点了,这样就变成了H+1个必经点,还超时过,囧~。当时思路就堵住了呢。

有暴搜代替这个状态DP,也能过,暴搜应该是更快吧,因为没有最优解的要求,只要能回到起始点就行。

/*

代码:


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int N=101;
const int NN=16;
const int inf=0x80808080;


int g[N][N],w[NN][NN];
int label[NN],c[NN],d[NN];
int T,n,m,num,sta;

bool dfs(int x,int money,int stat) {
    if(stat==(1<<num)-1 && money>=w[x][0]){
        return true;
    }
    for(int i=0;i<num;i++) if((stat&(1<<i))==0){
        if(money-d[i]-w[x][i]>=0) {
            if(dfs(i,money-d[i]-w[x][i]+c[i],stat^(1<<i))) return true;
        }
    }
    return false;
}

int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d%d",&n,&m,&sta);
        memset(g,0x3f,sizeof(g));
        for(int i=0;i<n;i++) g[i][i]=0;
        for(int i=0;i<m;i++) {
            int s,t,w;
            scanf("%d%d%d",&s,&t,&w);
            s--;t--;
            g[s][t]=min(g[s][t],w);
            g[t][s]=min(g[t][s],w);
        }
        scanf("%d",&num);

        int havezero=false;
        for(int i=0;i<num;i++) {
            scanf("%d%d%d",&label[i],&c[i],&d[i]);
            label[i]--;
            if(label[i]==0) {
                havezero=true;
                swap(label[i],label[0]);
                swap(c[i],c[0]);
                swap(d[i],d[0]);
            }
        }
        if(!havezero) {
            label[num]=c[num]=d[num]=0;
            swap(label[num],label[0]);
            swap(c[num],c[0]);
            swap(d[num],d[0]);
            num++;
        }
        for(int k=0;k<n;k++)
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++) g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
        for(int i=0;i<num;i++)
            for(int j=0;j<num;j++) w[i][j]=g[label[i]][label[j]];

        bool yes=dfs(0,sta,0);
        if(yes) puts("YES");
        else puts("NO");

    }
    return 0;
}


 

posted @ 2012-09-10 23:25  编程菜菜  阅读(400)  评论(0编辑  收藏  举报