HDU 4284 Travel

来源:互联网 发布:step镜头数据mmd 编辑:程序博客网 时间:2024/06/09 15:27

  floyd+状态DP,计算哈密顿回路。也就是先计算H个点的哈密顿路径,再判断能否构成起点为1的回路。

//2012-09-12 10:02:47Accepted42842531MS4364K1945 BG++Aros#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 100+5, MAXM = 10000+5;const int MAX = 16;const int INF = 0x3f3f3f3f;int T, N, M, Money, H, U, V, W;int chs[MAX], C[MAX], D[MAX];int d[MAXN][MAXN], f[1<<MAX][MAX];int main(){    scanf("%d", &T);    while (T--)    {        memset(f, -1, sizeof(f));        scanf("%d%d%d", &N, &M, &Money);        for (int i = 1; i <= N; i++)            for (int j = 1; j <= i; j++)                d[i][j] = d[j][i] = (i != j) ? INF : 0;        for (int i = 0; i < M; i++)        {            scanf("%d%d%d", &U, &V, &W);            if (W < d[U][V])                d[U][V] = d[V][U] = W;        }        for (int k = 1; k <= N; k++)            for (int i = 1; i <= N; i++)                for (int j = 1; j <= N; j++)                {                    if (d[i][k] < INF && d[k][j] < INF && d[i][j] > d[i][k]+d[k][j])                        d[i][j] = d[i][k]+d[k][j];                }        scanf("%d", &H);        for (int i = 0; i < H; i++)        {            scanf("%d%d%d", &chs[i], &C[i], &D[i]);            if (Money >= d[1][chs[i]]+D[i])                f[1<<i][i] = max(f[1<<i][i], Money-d[1][chs[i]]-D[i]+C[i]);        }        int tot = (1<<H)-1;        for (int u = 0; u < tot; u++)            for (int i = 0; i < H; i++) if (u&(1<<i))                for (int j = 0; j < H; j++) if (!(u&(1<<j)))                {                    int v = u|(1<<j);                    if (f[u][i] >= d[chs[i]][chs[j]]+D[j])                        f[v][j] = max(f[v][j], f[u][i]-d[chs[i]][chs[j]]-D[j]+C[j]);                }        bool flag = 0;        for (int i = 0; i < H && !flag; i++)            if (f[tot][i] >= d[chs[i]][1])                flag = 1;        if (flag)            printf("YES\n");        else            printf("NO\n");    }    return 0;}


原创粉丝点击