目录
设置S存放已被访问的结点,然后执行n次以下步骤,n为节点数目
实现:
①集合S可以用一个bool数组vis[]来实现
②令int数组d[]表示起点s到达顶点Vi的最短距离,初始时除了起点s的d[s]赋值为0,其余顶点都
复制为一个很大的数
- #include
- #include
- #include
- #include
- using namespace std;
-
- const int MAXV = 1000;//最大顶点数
- const int INF = 100000000;//设INF为一个很大的数
-
- int n, m, s;
- int G[MAXV][MAXV];//n为顶点数,
- int d[MAXV];//起点到达各点的最短路径长度
- bool vis[MAXV] = { false };//标记数组,true为一访问,
-
- void Dijkstra(int s) {
- fill(d, d + MAXV, INF);
- d[s] = 0;//起点s到达自身的距离为0
- for (int i = 0; i < n; i++) {//循环n次
- int u = -1, MIN = INF;//u使d[u]最小,MIN存放最小的d[u]
- for (int j = 0; j < n; j++) {
- if (vis[j] == false && d[j] < MIN) {
- u = j;
- MIN = d[j];
- }
- }
-
- //找不到小于INF的d[u],说明剩下的顶点和起点s不连通
- if (u == -1)return;
- vis[u] = true;//标记u为已访问
- for (int v = 0; v < n; v++) {
- //如果v未访问 && u能到达v && 以u为中介可以使d[v]更优
- if (vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]) {
- d[v] = d[u] + G[u][v];
- }
- }
- }
- }
-
- int main() {
- int u, v, w;
- cin >> n >> m >> s;
- fill(G[0], G[0] + MAXV * MAXV, INF);
- for (int i = 0; i < m; i++) {
- cin >> u >> v >> w;
- G[u][v] = w;
- }
- Dijkstra(s);
- for (int i = 0; i < n; i++) {
- printf("%d ", d[i]);
- }
-
- return 0;
- }
- #include
- using namespace std;
-
- const int MAXV = 1000;//最大顶点数
- const int INF = 100000000;//设INF为一个很大的数
-
- int n;
- int G[MAXV][MAXV];
- int d[MAXV];
- int pre[MAXV];
- bool vis[MAXV] = { false };
-
-
- void Dijkstra(int s) {
- fill(d, d + MAXV, INF);
- d[s] = 0;
- for (int i = 0; i < n; i++)pre[i] = i;//初始状态设每个点的前驱为自身
- 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 && d[u] + G[u][v] < d[v]) {
- d[v] = d[u] + G[u][v];
- pre[v] = u;//记录v的前去顶点是u
- }
- }
- }
- }
-
- void dfs(int s, int v) {
- if (v == s) {
- cout << s << endl;
- return;
- }
- dfs(s, pre[v]);
- cout << v << endl;
- }
对于这类题目,只需要新增加一个数组来存放新增的边权或点权或最短路径条数,然后再Dijkstra中修改优化d[v]的那个步骤即可,其他部分不需要改动
比如说花费,在最短路径有多条时选择花费最小的.
用cost[u][v]表示u到v的花费,并增加一个数组c[],令从起点s到达顶点u的最少花费为c[u],初始化时只有c[s]为0,其余c[u]均为INF,这样就可以在d[u[+G[u][v] 而当d[u]+G[u][v]==d[v]时,且c[u]+cost[u][v] 比如说每个城市收集到的物资,在最短路径有多条时选择收集物资最多的 用weight[u]表示城市u中的物资数目,并增加一个数组w[],令从起点s到达顶点u可以收集到的最大物资为w[u],初始化时只有w[s]为weight[s],其余w[u]均为0,d[u[+G[u][v] 而当d[u]+G[u][v]==d[v]时,且w[u]+weight[v]>w[v]时更新w[v]: 只需要增加一个数组num[],令从起点s到达顶点u的最短路径条数为num[u],初始化时只有nums[s]为1,其余num[u]为0,这样就可以在d[u]+G[u][v] 而当d[u]+G[u][v]==d[v]时,将num[u]加到num[v]上: 题目详情 - 1003 Emergency (pintia.cn) 1003 Emergency 分数 25 作者 CHEN, Yue 单位 浙江大学 As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible. Input Specification: Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C1 and C2 - the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2. Output Specification: For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line. Sample Input: Sample Output: 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 题意:给N个城市,M条无向边。每个城市有一定数目的救援小组,所有边的边权已知。现在给出起点和重点,求从起点到终点的最短路径条数以及最短路径上救援小组的数目之和,如果有多条最短路径,则输出数目之和最大的 1030 Travel Plan 分数 30 作者 CHEN, Yue 单位 浙江大学 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. Input Specification: 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: where the numbers are all integers no more than 500, and are separated by a space. Output Specification: For each test case, print in one line the cities along the shortest path from the starting point to the destination, followed by the total distance and the total cost of the path. The numbers must be separated by a space and there must be no extra space at the end of output. Sample Input: Sample Output: 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 题意:有N个城市,M条道路,并给出M条道路的距离属性和花费,给定起点S和目的地D,求从起点S到D的最短路径、最短距离和花费,如果有多条最短路径,选择花费最小的那条 floyd的算法时间复杂度为O(n^3),故顶点数n不能太大,一般不超过200 如果存在顶点k,使得以k作为中介点时顶点i和顶点j的当前最短距离缩短,则使用顶点k作为i和j的中介点。即当dis[i][k]+dis[k][j]给每个点增加一个点权
直接问有多少条最短路径
习题
PAT A1003 Emergency
2 4
PAT A1030 Travel Plan
City1 City2 Distance Cost
0 2 3 3 40
Floyd算法