万事须己运,他得非我贤。这篇文章主要讲述*51nod - 1459迷宫游戏(记录双向权值的Dijkstra单源最短路)相关的知识,希望能为你提供帮助。
题干:
你来到一个迷宫前。该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数。还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间。游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大。现在问题来了,给定房间、道路、分数、起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的最大得分是多少么?
Input
第一行4个整数n (<
=500), m, start, end。n表示房间的个数,房间编号从0到(n - 1),m表示道路数,任意两个房间之间最多只有一条道路,start和end表示起点和终点房间的编号。
第二行包含n个空格分隔的正整数(不超过600),表示进入每个房间你的得分。
再接下来m行,每行3个空格分隔的整数x, y, z (0
输入保证从start到end至少有一条路径。
Output
一行,两个空格分隔的整数,第一个表示你最少需要的时间,第二个表示你在最少时间前提下可以获得的最大得分。
Sample Input
3 2 0 2
1 2 3
0 1 10
1 2 11
Sample Output
21 6
解题报告:
此题采用邻接矩阵的方式储存图,加一个维护ans数组。
【*51nod - 1459迷宫游戏(记录双向权值的Dijkstra单源最短路)】AC代码:
#include< bits/stdc++.h>
using namespace std;
const int MAX = 505;
const int INF = 0x3f3f3f3f;
int maze[505][505];
bool vis[MAX];
int dis[505],ans[505];
int val[505];
int n,m,st,ed;
struct Point
int pos,w;
;
void Dijkstra(int u,int v)
dis[u] = 0;
int all = n, minw = INF, minv;
//for(int i = 0; i< n; i++) dis[i] = maze[u][i];
ans[u] = val[u];
for(int k = 1; k< =n; k++)
minw = INF; minv = u;
for(int i = 0; i< n; i++)
if(vis[i] ) continue;
if(dis[i] < minw)
minv = i; minw = dis[i];
vis[minv] = 1;
if(minv == v) break;
for(int i = 0; i< n; i++)
if(vis[i] == 0 & & maze[minv][i] !=INF)
if(dis[i] > dis[minv] + maze[minv][i])
dis[i] = min(dis[i],dis[minv]+maze[minv][i]);
ans[i] = ans[minv] +val[i];
else if(dis[i]==dis[minv]+maze[minv][i])
ans[i]=max(ans[i],ans[minv]+val[i]); //若路径花费相等,点权值取较大的。
//if(dis[v] !=INF)
printf("%d %d\\n",dis[v],ans[v]);
//else printf("-1\\n");
void init()
memset(ans,0,sizeof(ans));
memset(maze,INF,sizeof(maze));
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(val,0,sizeof(val));
int main()
int u,v,w;
while(~scanf("%d%d%d%d",& n,& m,& st,& ed) )
init();
for(int i = 0; i< n; i++)
scanf("%d",& val[i]);
while(m--)
scanf("%d%d%d",& u,& v,& w);
maze[u][v] = maze[v][u] = w;
Dijkstra (st,ed);
return 0 ;
//9:13
AC代码2:(用dfs路径还原)(还未看。。。。)
#include< stdio.h>
#include< algorithm>
#include< string.h>
#include< vector>
using namespace std;
const int INF=1e9+7;
const int maxm=505;
int cost[maxm][maxm],dis[maxm],vis[maxm],w[maxm],s,e,n,m,ans=0;
vector< int> p[maxm];
void dijkstra();
void dfs(int k,int sum);
int main()
int i,j,k,sum,x,y,z;
scanf(推荐阅读
- POJ - 1502MPI Maelstrom(Dijkstra单源最短路--求一点到其余个点的最小值的最大值)
- HDU - 2112 HDU Today(dijkstra单源最短路 + map转换)
- [ C++ ] 类与对象(下) 初始化列表,友元,static成员,内部类
- HDU - 1285确定比赛名次 (拓扑排序)
- POJ - 1789ZOJ - 2158SCU - 1832Truck History (最小生成树)
- POJ - 1751Highways (最小生成树)
- HDU - 3038How Many Answers Are Wrong (带权并查集--权为区间和)
- POJ - 3494Largest Submatrix of All 1’s(加一点思维后化成 单调栈)
- POJ - 2349UVA - 10369 Arctic Network(最小生成树求权值第k大的边)(内附两种算法)