题目描述
你来到一个迷宫前。该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数。还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间。游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大。现在问题来了,给定房间、道路、分数、起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的最大得分是多少么?
输入
第一行4个整数n (<=500), m, start, end。n表示房间的个数,房间编号从0到(n - 1),m表示道路数,任意两个房间之间最多只有一条道路,start和end表示起点和终点房间的编号。
第二行包含n个空格分隔的正整数(不超过600),表示进入每个房间你的得分。
再接下来m行,每行3个空格分隔的整数x, y, z (0<z<=200)表示道路,表示从房间x到房间y(双向)的道路,注意,最多只有一条道路连结两个房间,你需要的时间为z。
输入保证从start到end至少有一条路径。
输出
样例输入
<span style="color:#333333">3 2 0 2
1 2 3
0 1 10
1 2 11</span>
样例输出
<span style="color:#333333">21 6</span>
提示
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f;
//priority_queue<int,vector<int>,greater<int>>q;
int n,m,s_r,e_r;
int val[550];
int maze[550][550];
int vis[550];
int tim[550];
int sum[550];
void dfs()
{
int MIN,v;
for(int i=0;i<n;i++)//start find from room i
{
MIN=INF;
v=0;
for(int j=0;j<n;j++)//find the ith smallest time room v
{
if(!vis[j])
{
if(tim[j]<MIN)
{
MIN=tim[j];
v=j;
}
}
}
vis[v]=1;
for(int j=0;j<n;j++)//from room v to room j
{
if(!vis[j])
{
if(tim[j]>tim[v]+maze[v][j])//get the smaller time
{
tim[j]=tim[v]+maze[v][j];
sum[j]=sum[v]+val[j];//get value when enter room j
}
else if(tim[j]==tim[v]+maze[v][j])//equal condition,to get the bigger value
{
sum[j]=max(sum[j],sum[v]+val[j]);
}
}
}
}
}
int main()
{
cin>>n>>m>>s_r>>e_r;
for(int i=0;i<n;i++)
{
cin>>val[i];
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(i==j)
maze[i][j]=0;
else
maze[i][j]=INF;
}
}
for(int i=0;i<m;i++)
{
int x,y,t;
cin>>x>>y>>t;
maze[x][y]=t;
maze[y][x]=t;
}
memset(vis,0,sizeof(vis));
memset(tim,INF,sizeof(tim));
memset(sum,0,sizeof(sum));
tim[s_r]=0;
sum[s_r]=val[s_r];
dfs();
cout<<tim[e_r]<<" "<<sum[e_r]<<endl;
return 0;
}
dfs还要算得分,用时最少
void
dfs()
{
int
MIN,v;
for
(
int
i=0;i<n;i++)
//start find from room i
{
MIN=INF;
v=0;
for
(
int
j=0;j<n;j++)
//find the ith smallest time room v
{
if
(!vis[j])
{
if
(tim[j]<MIN)
{
MIN=tim[j];
v=j;
}
}
}
vis[v]=1;
for
(
int
j=0;j<n;j++)
//from room v to room j
{
if
(!vis[j])
{
if
(tim[j]>tim[v]+maze[v][j])
//get the smaller time
{
tim[j]=tim[v]+maze[v][j];
sum[j]=sum[v]+val[j];
//get value when enter room j
}
else
if
(tim[j]==tim[v]+maze[v][j])
//equal condition,to get the bigger value
{
sum[j]=max(sum[j],sum[v]+val[j]);
}
}
}
}
}