zoukankan      html  css  js  c++  java
  • Escape Time II(DFS搜索)

    Escape Time II
    Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

    Description

    There is a fire in LTR ’ s home again. The fire can destroy all the things in t seconds, so LTR has to escape in t seconds. But there are some jewels in LTR ’ s rooms, LTR love jewels very much so he wants to take his jewels as many as possible before he goes to the exit. Assume that the ith room has ji jewels. At the beginning LTR is in room s, and the exit is in room e.

    Your job is to find a way that LTR can go to the exit in time and take his jewels as many as possible.

    Input

    There are multiple test cases. 
    For each test case: 
    The 1st line contains 3 integers n (2 ≤ n ≤ 10), mt (1 ≤ t ≤ 1000000) indicating the number of rooms, the number of edges between rooms and the escape time.
    The 2nd line contains 2 integers s and e, indicating the starting room and the exit.
    The 3rd line contains n integers, the ith interger ji (1 ≤ ji ≤ 1000000) indicating the number of jewels in the ith room.
    The next m lines, every line contains 3 integers abc, indicating that there is a way between room a and room b and it will take c (1 ≤ c ≤t) seconds. 

    Output

    For each test cases, you should print one line contains one integer the maximum number of jewels that LTR can take. If LTR can not reach the exit in time then output 0 instead.

    Sample Input

    3 3 5
    0 2
    10 10 10
    0 1 1 
    0 2 2
    1 2 3
    5 7 9
    0 3
    10 20 20 30 20
    0 1 2
    1 3 5
    0 3 3
    2 3 2
    1 2 5
    1 4 4
    3 4 2

    Sample Output

    30
    80

    这很显然是一道搜索题,用DFS可以很方便地解决。程序雏形很快就编出来了,可是很多细节问题没注意,结果WA了几次,T.T

    做个总结,留下经验:

    1.开始时我是标记顶点(就是room)而非路径,但此题是允许环的存在的,比如A — B — A,如果标记顶点的话,由A再到B就不行了。所以标记路径,从A到B时就标记路径<A,B>,做标记是为了避免重复走同一路径,为什么要避免?显然再次走<A,B>时已经不能收获jewel又要耗费时间。

    2.虽然顶点不需标记,但对已经搜索过的顶点,要将其含有的jewel数清零。一开始我就没注意到这点。

    3.恢复现场的工作要做好。

    4.到达e不能马上停下,如果此时总时间不超过规定时间 t 的话,还可以搜索其他顶点以获得更多的jewel,但最终一定要再回到e,每次到e都要更新获取jewel的最大数量。


    AC code:

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    
    int n, m, t, s, e;
    int jew[10], cost[10][10], maxjew;
    bool vis[10][10];
    
    //r:room, sj:sum of jewels, st:sum of time
    void DFS(int r, int sj, int st)
    {
        if(r == e && sj > maxjew)
            maxjew = sj;
        for(int i = 0; i < n; i++)
        {
            if(!vis[r][i] && cost[r][i] && r != i && st + cost[r][i] <= t)
            {
                //因为往下一层递归时jew[i]要设为0,故此处保存其值以还原
                int val = jew[i];
                jew[i] = 0;
                //注意不是vis[r][i]=vis[i][r]=1,因为路径可以构成环,比如A-B-A,如果
                //从A到B的同时标记B到A的路径,就可能造成搜索B后到不了e(如必须到经A到e)
                vis[r][i] = 1;
                DFS(i, sj + val, st + cost[r][i]);
                vis[r][i] = 0;
                jew[i] = val;
            }
        }
        return ;
    }
    
    int main()
    {
        while(scanf("%d %d %d", &n, &m, &t) != EOF)
        {
            //初始化
            memset(cost, 0, sizeof(cost));
            memset(vis, 0, sizeof(vis));
            maxjew = 0;
            //输入
            scanf("%d %d", &s, &e);
            for(int i = 0; i < n; i++)
                scanf("%d", &jew[i]);
            for(int j = 0, a, b; j < m ;j++)
            {
                scanf("%d %d", &a, &b);
                scanf("%d", &cost[a][b]);
                cost[b][a] = cost[a][b];
            }
            //dfs
            int val = jew[s];
            jew[s] = 0; //s处的jewel一开始就被拿走
            DFS(s, val, 0);
            //输出
            printf("%d\n", maxjew);
        }
        return 0;
    }
    


  • 相关阅读:
    swift计算 switch case
    BUUCTF--reverse1
    BUUCTF--easyer
    Windows程序设计(七)--鼠标
    攻防世界--maze
    Windows 程序设计--(六)键盘
    攻防世界--csaw2013reversing2
    攻防世界--getit
    攻防世界--python-trade
    Windows程序设计--(五)绘图基础
  • 原文地址:https://www.cnblogs.com/cszlg/p/2910568.html
Copyright © 2011-2022 走看看