ZOJ 3620 Escape Time II

时间:2022-05-08
本文章向大家介绍ZOJ 3620 Escape Time II,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意:

     从初始房间到达终止房间需要经过一系列的房间,没经过一个房间会得到一个价值,从一个房间到达另一个房间同时需要消耗一定的时间,在规定的时间内从初始到达终止房间          所能达到的最大值是多少

#include<stdio.h>
#include<string.h>
#define INF 99999999
const int MAXN=15;

int mp[MAXN][MAXN];//储存路径以及时间
int vis_room[MAXN];//标记房间是否走过
int vis_edge[MAXN][MAXN];//标记这条路是否走过
int jewel[MAXN];//每个房间的价值
int ans1;//储存最大的价值
int n,m,t;//房间数量,路径数量,规定的时间
int s,e;//初始房间,终止房间
//主要思想房间走过无所谓,路径走过不要再走了
void DFS(int s,int value,int time)
{
    int flag;
    if(value==INF) return;//房间不可达到
    if(s==e && value>ans1) ans1=value;//到达了终点并且价值大,替换
    for (int i=0;i<n;i++)
    {
        flag=0;
        if(mp[s][i]!=INF && vis_edge[s][i]==0 && time+mp[s][i]<=t)//房间可以到达,并且路径没有走过
        { 
            if(vis_room[i]==0)
            {
                flag=1;
                value+=jewel[i];//走过的房间财富不用加
                vis_room[i]=1;
            }
            vis_edge[s][i]=1;
            DFS(i,value,time+mp[s][i]);//房间走过了财富不用加,时间继续加
            //if(i!=初始房间)//这句话有没有无所谓,只是多搜了几步而已,不过也要注意
            if(flag)//若该房间以前走过了,价值就不需要减
            {
                value-=jewel[i];  
                vis_room[i]=0;
            }
            vis_edge[s][i]=0; 
        }
    }
}

int main()
{
    int a,b,c;
    int i,j;
    while(scanf("%d%d%d",&n,&m,&t)!=EOF)
    {
        ans1=ans2=0;
        memset(vis_room,0,sizeof(vis_room));
        memset(vis_edge,0,sizeof(vis_edge));
        scanf("%d%d",&s,&e);
        for (i=0;i<n;i++)
            for (j=0;j<n;j++)
                mp[i][j]=INF;    
            for (i=0;i<n;i++)
                scanf("%d",&jewel[i]);
            for (i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                mp[a][b]=c;
                mp[b][a]=c;
            }
            vis_room[s]=1;
            //这里是wrong的原因,初始房间不一定是0;
            DFS(s,jewel[s],0);//位置,初始房间财宝价值,所用时间
            printf("%dn",ans1);
    }
    return 0;
}