题目:
你来到一个迷宫前。该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数。还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间。游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大。现在问题来了,给定房间、道路、分数、起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的最大得分。
最短路问题,分别用SPFA和dijkstra做一下。
SPFA:
#include <cstdio>
#include <iostream>
#include <stack>
#include <queue>
#include <cstring>
using namespace std;
typedef long long LL;
const int INF=0x3f3f3f3f;
const int N=5e2+10;
int val[N];
struct asd{
int w;
int to;
int next;
};
asd q[N*N];
int head[N*N],tol,dis[N],d[N];
int n,m,s,t;
bool vis[N];
queue<int>e;
void spfa()
{
while(!e.empty())
e.pop();
for(int i=0;i<n;i++)
{
dis[i]=INF;
d[i]=0;
vis[i]=false;
}
d[s]=val[s];
dis[s]=0;
vis[s]=true;
e.push(s);
while(!e.empty())
{
int u=e.front();e.pop();
vis[u]=0;
for(int v=head[u];v!=-1;v=q[v].next)
{
int i=q[v].to;
if(dis[i]>dis[u]+q[v].w)
{
dis[i]=dis[u]+q[v].w;
d[i]=d[u]+val[i];
if(!vis[i])
{
vis[i]=1;
e.push(i);
}
}
else if(dis[i]==(dis[u]+q[v].w))
{
if(d[i]<d[u]+val[i])
d[i]=d[u]+val[i];
}
}
}
printf("%d %d\n",dis[t],d[t]);
}
void add(int a,int b,int c)
{
q[tol].to=b;
q[tol].w=c;
q[tol].next=head[a];
head[a]=tol++;
}
void init()
{
memset(head,-1,sizeof(head));
tol=0;
}
int main()
{
scanf("%d",&n);
scanf("%d",&m);
scanf("%d%d",&s,&t);
for(int i=0;i<n;i++)
scanf("%d",&val[i]);
init();
while(m--)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
spfa();
return 0;
}
②Dijkstra:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxx 999999
int map[501][501];
int n,m,st,en,f[501],mark[501],sum[501],a[501];
void Dijkstra()
{
int i,j,k,min;
memset(mark,0,sizeof(mark));
sum[st]=a[st];
for(i=0;i<n;i++)
{
f[i]=map[st][i];
}
f[st]=0;
for(i=0;i<n;i++)
{
min=maxx;
for(j=0;j<n;j++)//找出第i个离起点最近的距离,找到后把此点标记为k,mark[k]=1,表示要走这段路了,以后不再找了
{
if(!mark[j]&&f[j]<min)
{
min=f[j];
k=j;
}
}
if(min==maxx)break;//没路了就跳出
mark[k]=1;
for(j=0;j<n;j++)
{
if(!mark[j]&&f[j]>=f[k]+map[k][j])
{
// printf("%d %d %d %d %d %d\n",i,j,k,f[j],f[k],map[k][j]);
if(f[j]==f[k]+map[k][j])
{
sum[j]=max(sum[j],sum[k]+a[j]);
}
else
{
f[j]=f[k]+map[k][j];
sum[j]=sum[k]+a[j];
}
}
}
}
if(f[en]!=maxx)printf("%d %d\n",f[en],sum[en]);
else printf("-1\n");
}
int main()
{
int x,y,z,i,j;
while(scanf("%d%d%d%d",&n,&m,&st,&en)!=EOF)
{
for(i=0;i<=n-1;i++)
for(j=0;j<=n-1;j++)
map[i][j]=maxx;//map[i][j]表示从i到j所要花费的距离
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(i=1;i<=m;i++)
{
scanf("%d %d %d",&x,&y,&z);
if(map[x][y]>z)
{map[x][y]=map[y][x]=z;}
}
Dijkstra();
}
return 0;
}