2012 ACM/ICPC Asia Regional Tianjin Online Travel

http://acm.hdu.edu.cn/showproblem.php?pid=4284

思路:预处理15个点之间的最短距离后暴力。

View Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
const int maxn = 105;
const int inf = 1<<29;
int dis[maxn][maxn];
int h[maxn],d[maxn],c[maxn],vis[maxn];
int N,M,H,tot,ok;
void floyd()
{
    int i,j,k;
    for( k=0; k<=N; k++ )
        for( i=0; i<=N; i++ )if( k!=i )
            for( j=0; j<=N; j++ )if(j!=i&&j!=k){
                if( dis[i][j]>dis[i][k]+dis[k][j] )
                    dis[i][j]=dis[i][k]+dis[k][j];
            }
}
void dfs(int x,int res,int cnt)
{
    int i;
    if(cnt==H){
        if(res>=dis[x][1])ok=1;
        return;
    }
    if(ok)return ;
    vis[x]=1;
    for(i = 0; i < H; ++ i)if(!vis[h[i]]){
        int cost = d[i] + dis[x][h[i]];
        if(res>=cost)
            dfs(h[i],res-cost+c[i],cnt+1);
    }
    vis[x]=0;
}
int main()
{
    int i,j,k,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d %d",&N,&M,&tot);
        for(i = 0 ; i <= N; ++ i)
            for(j = 0; j <= N; ++ j)
                if(i^j)dis[i][j]=inf;
                else dis[i][j] = 0;
        for(i = 0; i < M; ++ i){
            int u,v,w;
            scanf("%d %d %d",&u,&v,&w);
            if(dis[u][v]>w)dis[u][v]=dis[v][u]=w;
        }
        dis[0][1] = dis[1][0] = 0;
        scanf("%d",&H);
        for(i = 0; i < H; ++ i)
            scanf("%d %d %d",h+i,c+i,d+i);
        floyd();
        ok = 0;
        memset(vis,0,sizeof(vis));
        dfs(0,tot,0);
        if(ok)puts("YES");
        else puts("NO");
    }
    return 0;
}

posted on 2012-09-09 18:11  aigoruan  阅读(289)  评论(0)    收藏  举报

导航