题目
A traveler’s map gives the distances between cities along the highways, together with the cost of each highway. Now you are supposed to write a program to help a traveler to decide the shortest path between his/her starting city and the destination. If such a shortest path is not unique, you are supposed to output the one with the minimum cost, which is guaranteed to be unique.
Each input file contains one test case. Each case starts with a line containing 4 positive integers N, M, S, and D, where N (≤500) is the number of cities (and hence the cities are numbered from 0 to N−1); M is the number of highways; S and D are the starting and the destination cities, respectively. Then M lines follow, each provides the information of a highway, in the format
详细题目看原链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805464397627392
题目大意就是给出一个无向图,边权有两种,一种是距离,另一种是金钱,现要求给出起点和终点,输出最短路径、最短距离和最少花费。
分析
采用迪杰斯克拉算法解题,创建d【】和c【】记录最短距离和最少花费。
创建pre【】记录路径。
直接上代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxv = 510;
const int INF = 0x3fffffff;
int n, m, st, ed, G[maxv][maxv], cost[maxv][maxv];
int d[maxv], c[maxv], pre[maxv];
bool vis[maxv] = {false};
void dijsk(int s)
{
fill(d, d+maxv, INF);
fill(c, c+maxv, INF);
for(int i = 0; i < n; i++) pre[i] = i;
d[s] = 0;
c[s] = 0;
for(int i = 0; i < n; i++)
{
int u = -1, MIN = INF;
for(int j = 0; j < n; j++)
{
if(vis[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
}
if(u == -1) return;
vis[u] = true;
for(int v = 0; v < n; v++)
{
if(vis[v] == false && G[u][v] != INF)
{
if(d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
c[v] = c[u] + cost[u][v];
pre[v] = u;
}
else if(d[u] + G[u][v] == d[v])
{
if(c[u] + cost[u][v] < c[v])
{
c[v] = c[u] + cost[u][v];
pre[v] = u;
}
}
}
}
}
}
void dfs(int s)
{
if(s == st)
{
printf("%d ", s);
return;
}
dfs(pre[s]);
printf("%d ", s);
}
int main()
{
scanf("%d%d%d%d", &n, &m, &st, &ed);
int u, v;
fill(G[0], G[0] + maxv*maxv, INF);
for(int i = 0; i < m; i++)
{
scanf("%d%d", &u, &v);
scanf("%d%d", &G[u][v], &cost[u][v]);
G[v][u] = G[u][v];
cost[v][u] = cost[u][v];
}
dijsk(st);
dfs(ed);
printf("%d %d", d[ed], c[ed]);
return 0;
}
收获
1.这是一类套模板的题,只要你模板熟悉,往上套就完事。
2.这类题一般是除了求最短路径外还参合着第二标尺如点权,新增边权,最短路径的条数等等,这些新增的元素只需要再更新d【】的时候同时更新即可解决。
3.为了方便记忆,迪杰斯克拉算法可归纳成三步走:一初始化(图和其他),二找最小d【】,三找中间变量v,收工。