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;
}


posted on 2012-08-09 17:00  铁树银花  阅读(251)  评论(0编辑  收藏  举报

导航