zoukankan      html  css  js  c++  java
  • HDU 4284 Travel (Folyd预处理+dfs暴搜)

    题意:给你一些N个点,M条边,走每条边要花费金钱,然后给出其中必须访问的点,在这些点可以打工,但是需要先拿到证书,只可以打一次,也可以选择不打工之直接经过它。一个人从1号点出发,给出初始金钱,问你能不能访问所以的点,并且获得所以证书。

    题解:目标是那些一定要访问的点,怎么到达的我们不关心,但是我们关心花费最少的路径,而且到达那个点后是一定要打工的,如果只是经过,那么在求花费最少的路径的时候已经考虑过了。

    因此先用Folyd求出各个点直接的最短路径,由于N很小,又只要求出一个解,所以直接dfs暴搜就行了。

    M很大,可能有重边。注意处理。

    当时一看,图论题,没仔细想就跳过了。下面的代码加了输入挂,因为第一遍写T了,以为是输入问题,所以加上了。改了我好几个小时没过,重写一遍就过了。

    #define HDU
    #ifndef HDU
    #include<bits/stdc++.h>
    #else
    //pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    //#include<iostream>
    #endif // HDU
    #define mins(s,x) if((x)<(s)) s = x
    #define maxs(s,x) if((x)>(s)) s = x
    using namespace std;
    typedef long double ld;
    typedef long long ll;
    
    
    const int maxn = 105;
    const int maxh = 20;
    const int INF = 0x3f3f3f3f;
    
    int N,M,Mon,H;
    int dis[maxn][maxn];
    inline void scan_d(int &ret)
    {
        char c;ret=0;
        while((c=getchar())<'0'||c>'9');
        while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
    }
    
    struct City
    {
        int cost,earn,id;
        void input(){
            scanf("%d%d%d",&id,&earn,&cost);
        }
    }city[maxh];
    
    
    bool vis[maxh];
    
    
    
    bool dfs(int u,int money,int cnt)
    {
        if( cnt == H && money >= dis[u][1] )return true;
        for(int i = 0; i < H; i++) if(!vis[i]){
            int v = city[i].id;
            if( money >= dis[u][v]+city[i].cost ){
                vis[i] = 1;
                if(dfs(v,money-dis[u][v]-city[i].cost+city[i].earn,cnt+1)) return true;
                vis[i] = 0;
            }
        }
        return false;
    }
    
    void init()
    {
        memset(vis,false,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        for(int i = 1; i <= N; i++)
            dis[i][i]= 0;
    }
    
    //#define local
    
    int main()
    {
    #ifdef local
        freopen("in.txt","r",stdin);
       // freopen("myout.txt","w",stdout);
    #endif // local
        int T;
        scan_d(T);
        //scanf("%d",&T);
        while(T--){
            scan_d(N);scan_d(M);scan_d(Mon);
            //scanf("%d%d%d",&N,&M,&Mon);
            init();
            for(int i = 0; i < M; i++){
                int u,v,w;
                scan_d(u);scan_d(v);scan_d(w);
                //scanf("%d%d%d",&u,&v,&w);
                //if(u == v) continue;
                if(dis[u][v]>w) {
                    dis[u][v] = w;
                    dis[v][u] = dis[u][v];
                }
    
            }
    
            for(int k = 1; k <= N; k++)
                for(int i = 1; i <= N; i++){
                    if(dis[i][k]<INF)
                    for(int j = 1; j <= N; j++) {
                        mins(dis[i][j],dis[i][k]+dis[k][j]);
                    }
                }
    
            scanf("%d",&H);
            for(int i = 0; i < H; i++){
                city[i].input();
            }
    
            printf("%s
    ",dfs(1,Mon,0)?"YES":"NO");
        }
    
        return 0;
    }
  • 相关阅读:
    复合词 (Compund Word,UVa 10391)
    卡片游戏 (Throwing card away I,UVa10935)
    交换学生 (Foreign Exchange,UVa10763)
    Ducci序列 (Ducci Sequence,ACM/ICPC Seoul 2009,UVa1594)
    代码对齐 (Alignment of Code,ACM/ICPC NEERC 2010,UVa1593)
    打印队列 (Printer Queue,ACM/ICPC NWERC 2006,UVA12100)
    更新字典 (Updating a Dictionary,UVa12504)
    golang 定时弹出对话框
    重新梳理一下adb操作app(golang版)
    通过无线网络使用ADB ( Connect to android with ADB over TCP )
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4665683.html
Copyright © 2011-2022 走看看