51nod1459迷宫问题—(迪杰斯特拉)
你来到一个迷宫前。该迷宫由若干个房间组成,每个房间都有一个得分,第一次进入这个房间,你就可以得到这个分数。还有若干双向道路连结这些房间,你沿着这些道路从一个房间走到另外一个房间需要一些时间。游戏规定了你的起点和终点房间,你首要目标是从起点尽快到达终点,在满足首要目标的前提下,使得你的得分总和尽可能大。现在问题来了,给定房间、道路、分数、起点和终点等全部信息,你能计算在尽快离开迷宫的前提下,你的最大得分是多少么?
Input
第一行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至少有一条路径。
Output
一行,两个空格分隔的整数,第一个表示你最少需要的时间,第二个表示你在最少时间前提下可以获得的最大得分。
Input示例
3 2 0 2 1 2 3 0 1 10 1 2 11
Output示例
21 6
题意:中文题。。。。。。
思路:迪杰斯特拉求最短路。但与模板不同,这里添加了分值这一个变量。所以,如果遇见了两条一样长的路,则取能够获得的分值较高的那一条。
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<cmath> 6 #include<algorithm> 7 #include<stack> 8 #include<climits> 9 #include<queue> 10 #define eps 1e-7 11 #define ll long long 12 #define inf 0x3f3f3f3f 13 #define pi 3.141592653589793238462643383279 14 using namespace std; 15 struct node{ 16 int far,mark; 17 }; 18 19 int map[505][505],visit[505],value[505]; 20 21 void Dijkstra(int start,int end,int n) 22 { 23 node d[505]; 24 for(int i=0; i<n; ++i) 25 { 26 d[i].mark = value[i];//初始化起点到达每个点的分值为这个点输入的分值 27 d[i].far = map[start][i]; 28 } 29 visit[start] = 1; 30 31 int Min,flag,num = n; 32 while(--num) 33 { 34 Min = inf; 35 for(int i=0; i<n; ++i) 36 { 37 if(!visit[i] && d[i].far < Min) //找出没走过的点中,起点能到达的最近的点 38 { 39 Min = d[i].far; 40 flag = i; 41 } 42 } 43 44 visit[flag] = 1; 45 46 for(int j=0; j<n; ++j) //更新路径 47 { 48 if(!visit[j]) 49 { 50 if(map[flag][j] + d[flag].far < d[j].far) //如果起点到 j 的距离比通过flag到 j 的距离长 51 { //就更新d[j]的长度为通过flag到 j 的长度 52 d[j].far = map[flag][j] + d[flag].far; 53 d[j].mark = d[flag].mark + value[j]; 54 } 55 else if(map[flag][j] + d[flag].far == d[j].far) //一样长就取分值较大的 56 { 57 d[j].mark = max(d[flag].mark + value[j], d[j].mark); 58 } 59 } 60 } 61 } 62 if(start == end) 63 cout<<d[end].far<<' '<<d[end].mark<<endl; 64 else 65 cout<<d[end].far<<' '<<d[end].mark + value[start]<<endl; 66 } 67 68 int main() 69 { 70 int n,m,start,end; 71 while(cin>>n>>m>>start>>end) 72 { 73 for(int i=0; i<n; ++i) //初始化两点之间的距离为无穷大,自己到自己为0 74 for(int j=0; j<n; ++j) 75 { 76 if(i == j) 77 map[i][j] = map[j][i] = 0; 78 else 79 map[i][j] = map[j][i] = inf; 80 } 81 82 memset(visit,0,sizeof(visit)); 83 84 for(int i=0; i<n; ++i) 85 scanf("%d",&value[i]); 86 87 int a,b,weight; 88 for(int i=0; i<m; ++i) 89 { 90 scanf("%d%d%d",&a,&b,&weight); 91 if(map[a][b] > weight) 92 map[a][b] = map[b][a] = weight; 93 } 94 Dijkstra(start,end,n); 95 } 96 return 0; 97 }