PAT练习笔记——10.4 最短路径

2019年9月PAT - 练习笔记——10.4

以下页码标注的是阅读器中实际页码,而不是书本身自印的页码。

第10章 提高篇(4)——图算法专题

10.4 最短路径

目录

  1. A1003 Emergency
  2. A1018 Public Bike Management
  3. A1030 Travel Plan
  4. A1072 Gas Station
  5. A1087 All Roads Lead to Rome

  1. A1003 Emergency

    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:
    5 6 0 2
    1 2 1 5 3
    0 1 1
    0 2 2
    0 3 1
    1 2 1
    2 4 1
    3 4 1
    
    Sample Output:
    2 4
    
    1. 我的

      #include <iostream>
      #include <vector>
      #include <queue>
      
      using namespace std;
      
      const int INF = 0x7fffffff;
      int n = 0, m = 0, c1 = 0, c2 = 0;
      vector<int> teams;
      vector<vector<int>> roads;
      
      int minLen = INF, pathAmount = 1, teamAmount = 0;
      vector<bool> visit;
      void DFS(int now, int sum, int team)
      {
      	if (now == c2) {
      		if (sum < minLen) {
      			minLen = sum;
      			pathAmount = 1;
      			teamAmount = team;
      		}
      		else if (sum == minLen) {
      			++pathAmount;
      			if (team > teamAmount) teamAmount = team;
      		}
      		return;
      	}
      	
      	for (int i = 0;i < n;++i) {
      		if (!visit[i] && roads[now][i]) {
      			visit[i] = true;
      			DFS(i, sum + roads[now][i], team + teams[i]);
      			visit[i] = false;
      		}
      	}
      }
      
      int main(void)
      {
      	scanf("%d %d %d %d", &n, &m, &c1, &c2);
      	teams.resize(n, 0);
      	roads.resize(n, vector<int>(n, 0));
      	visit.resize(n, false);
      	visit[c1] = true;
      	
      	for (int i = 0;i < n;++i) scanf("%d", &teams[i]);
      	for (int i = 0;i < m;++i) {
      		int city1 = 0, city2 = 0, len = 0;
      		scanf("%d %d %d", &city1, &city2, &len);
      		roads[city1][city2] = roads[city2][city1] = len; 
      	}
      	DFS(c1, 0, teams[c1]);
      	printf("%d %d", pathAmount, teamAmount);
      	
          return 0;
      }
      
    2. 《算法笔记》P358

      “本题在求解最短距离的同时需要求解另外两个信息:最短路径条数和最短路径上的最大点权之和。因此可以直接使用配套用书讲解的方法,以w[u]表示从起点s到达顶点u可以得到的最大点权之和,初始为0;以num[u]表示从起点s到达顶点u的最短路径条数,初始化时只有num[s]为1、其余num[u]均为0。接下来就可以在更新d[v]时同时更新这两个数组”

      #include <cstdio>
      #include <cstring>
      #include <algorithm>
      
      using namespace std;
      
      const int MAXV = 510;
      const int INF = 1000000000;
      
      // n为顶点数,m为边数,st和ed分别为起点和重点
      // G为邻接矩阵,weight为点权
      // d[]记录最短距离,w[]记录最大点权之和,num[]记录最短路径条数
      int n, m, st, ed, G[MAXV][MAXV], weight[MAXV];
      int d[MAXV], w[MAXV], num[MAXV];
      bool vis[MAXV] = {false};
      
      void Dijkstra(int s)
      {
          fill(d, d + MAXV, INF);
          memset(num, 0, sizeof(num));
          memset(w, 0, sizeof(w));
          d[s] = 0;
          w[s] = weight[s];
          num[s] = 1;
          
          for (int i = 0;i < n;i++) {
              int u = -1, MIN = INF;
              for (int j = 0;j < n;j++) {	// 找到未访问的顶点中d[]最小的
                  if (vis[j] == false && d[j] < MIN) {
                      u = j;
                      MIN = d[j];
                  }
              }
              if (u == -1) return; // 找不到小于INF的d[u],说明剩下的顶点和起点s不连通
              vis[u] = true;
              for (int v = 0;v < n;v++) {
                  if (vis[v] == false && G[u][v] != INF) { // 如果v未访问 && u能到达v
                      if (d[u] + G[u][v] < d[v]) { // 以u为中介点时能令d[v]变小
                          d[v] = d[u] + G[u][v];
                          w[v] = w[u] + weight[v];
                          num[v] = num[u];
                      }
                      else if (d[u] + G[u][v] == d[v]) {
                          if (w[u] + weight[v] > w[v]) {
                              w[v] = w[u] + weight[v];
                          }
                          // 注意最短路径条数与点权无关,必须写在外面
                          num[v] += num[u];
                      }
                  }
              }
          }
      }
      
      int main()
      {
          scanf("%d%d%d%d", &n, &m, &st, &ed);
          for (int i = 0;i < n;i++) scanf("%d", &weight[i]);
          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", &G[u][v]);
              G[v][u] = G[u][v];
          }
          Dijkstra(st);
          printf("%d %d\n", num[ed], w[ed]);
          return 0;
      }
      

  2. A1018 Public Bike Management

    There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city.

    The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.

    When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.

    img

    The above figure illustrates an example. The stations are represented by vertices and the roads correspond to the edges. The number on an edge is the time taken to reach one end station from another. The number written inside a vertex S is the current number of bikes stored at S. Given that the maximum capacity of each station is 10. To solve the problem at S3, we have 2 different shortest paths:

    1. PBMC -> S1 -> S3. In this case, 4 bikes must be sent from PBMC, because we can collect 1 bike from S1 and then take 5 bikes to S3, so that both stations will be in perfect conditions.
    2. PBMC -> S2 -> S3. This path requires the same time as path 1, but only 3 bikes sent from PBMC and hence is the one that will be chosen.
    Input Specification:

    Each input file contains one test case. For each case, the first line contains 4 numbers: Cmax (≤100), always an even number, is the maximum capacity of each station; N (≤500), the total number of stations; Sp, the index of the problem station (the stations are numbered from 1 to N, and PBMC is represented by the vertex 0); and MMM, the number of roads. The second line contains N non-negative numbers Ci (i=1,⋯,N) where each Ci is the current number of bikes at Si respectively. Then M lines follow, each contains 3 numbers: Si, Sj, and Tij which describe the time Tij taken to move betwen stations Si and Sj. All the numbers in a line are separated by a space.

    Output Specification:

    For each test case, print your results in one line. First output the number of bikes that PBMC must send. Then after one space, output the path in the format: 0−>S1−>⋯−>Sp. Finally after another space, output the number of bikes that we must take back to PBMC after the condition of Sp is adjusted to perfect.

    Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC. The judge’s data guarantee that such a path is unique.

    Sample Input:
    10 3 2 5
    6 7 0
    0 1 1
    0 2 1
    0 3 3
    1 3 1
    2 3 1
    
    Sample Output:
    3 0->2->3 0
    
    1. 我的

      单车数量这块真的写死我了orz
      算法没设计好会无意把后面的车补到之前缺的点上
      只使用Dijkstra,即默认minNeed和minRemain在路径上的传递满足最优子结构,则无法通过测试点7
      
    2. 《算法笔记》P369

      1. “为了便于编写代码,不妨把每个点的点权(自行车数目)都减去Cmax / 2,这样就可以用点权的正负来直接判断当前车站是需要补给还是需要带走额外的车辆。由于需要输出应从PBMC携带的自行车数目与从问题车站带回的自行车数目,因此对每个顶点来说需要增加两个属性:从PBMV到当前车站必须携带的自行车数目Need以及到达当前车站时手上多余的自行车数目Remain。显然,如果当前车站u的点权weight[u]为正,说明需要从该车站额外带走自行车,因此新的Remain等于就的Remain加上weight[u];而如果当前车站u的点权weight[u]为负,说明当前车站需要补给自行车的数量为abs(weight[u]),此时如果Remain大于0,就可以用来补给当前车站,但如果Remain不够完全补给,剩余部分需要从PBMC携带,故Need增加这个数值。“
      2. “题意中最重要的“陷阱”:从起点PBMC出发到达问题站点Sp的过程中就要把路径上所有站点都调整为最优状态,此后不再调整;并且决策时以距离作为第一标尺,当……”
      3. 本题不能只使用Dijkstra来解决,因为minNeed和minRemain在路径上的传递不满足最优子结构(不是简单的相加过程)。也就是说,只有当所有路径都确定后,才能去选择最小的need和最小的remain。
      #include <cstdio>
      #include <cstring>
      #include <vector>
      #include <algorithm>
      
      using namespace std;
      
      const int MAXV = 510;
      const int INF = 1000000000;
      int n, m, Cmax, Sp, numPath = 0, G[MAXV][MAXV], weight[MAXV];
      int d[MAXV], minNeed = INF, minRemain = INF;
      bool vis[MAXV] = {false};
      vector<int> pre[MAXV];
      vector<int> tempPath, path;
      
      void Dijkstra(int s)
      {
          fill(d, d + MAXV, INF);
          d[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];
                          pre[v].clear();
                          pre[v].push_back(u);
                      }
                      else if (d[u] + G[u][v] == d[v]) pre[v].push_back(u);
                  }
              }
          }
      }
      void DFS(int v)
      {
          if (v == 0) {
              tempPath.push_back(v);
              int need = 0, remain = 0;
              for (int i = tempPath.size() - 1;i >= 0;i--) {
                  int id = tempPath[i];
                  if (weight[id] > 0) remain += weight[id];
                  else {
                      if (remain > abs(weight[id])) remain -= abs(weight[id]);
                      else {
                          need += abs(weight[id]) - remain;
                          remain = 0;
                      }
                  }
              }
              if (need < minNeed) {
                  minNeed = need;
                  minRemain = remain;
                  path = tempPath;
              }
              else if (need == minNeed && remain < minRemain) {
                  minRemain = remain;
                  path = tempPath;
              }
              tempPath.pop_back();
              return;
          }
          tempPath.push_back(v);
          for (int i = 0;i < pre[v].size();i++) DFS(pre[v][i]);
          tempPath.pop_back();
      }
      
      int main()
      {
          scanf("%d%d%d%d", &Cmax, &n, &Sp, &m);
          int u, v;
          fill(G[0], G[0] + MAXV * MAXV, INF);
          for (int i = 1;i <= n;i++) {
              scanf("%d", &weight[i]);
              weight[i] -= Cmax / 2;
          }
          for (int i = 0;i < m;i++) {
              scanf("%d%d", &u, &v);
              scanf("%d", &G[u][v]);
              G[v][u] = G[u][v];
          }
          Dijkstra(0);
          DFS(Sp);
          printf("%d ", minNeed);
          for (int i = path.size() - 1;i >= 0;i--) {
              printf("%d", path[i]);
              if (i > 0) printf("->");
          }
          printf(" %d", minRemain);
          return 0;
      }
      

  3. A1030 Travel Plan

    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:

    City1 City2 Distance Cost
    

    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:
    4 5 0 3
    0 1 1 20
    1 3 2 30
    0 3 4 10
    0 2 2 20
    2 3 1 20
    
    Sample Output:
    0 2 3 3 40
    
    1. 我的

      #include <iostream>
      #include <vector>
      
      using namespace std;
      
      const int INF = 0x7fffffff;
      int n = 0, m = 0, s = 0, dest = 0;
      vector<vector<int>> roads, costs, pre;
      vector<int> d;
      
      void Dijkstra(int s)
      {
      	pre.resize(n);
      	d.resize(n, INF);
      	d[s] = 0;
      	vector<bool> visit(n, false);
      	
      	for (int i = 0;i < n;++i) {
      		int u = -1, min = INF;
      		for (int j = 0;j < n;++j) {
      			if (!visit[j] && d[j] < min) {
      				u = j;
      				min = d[j];
      			}
      		}
      		if (u == -1) return;
      		visit[u] = true;
      		for (int v = 0;v < n;++v) {
      			if (!visit[v] && roads[u][v]) {
      				int newd = d[u] + roads[u][v];
      				if (d[v] > newd) {
      					d[v] = newd;
      					pre[v].clear();
      					pre[v].push_back(u);
      				}
      				else if (d[v] == newd) pre[v].push_back(u);
      			}
      		}
      	}
      }
      
      int minCost = INF;
      vector<int> tmp, path;
      void DFS(int now, int sum)
      {
      	if (now == s) {
      		if (sum < minCost) {
      			minCost = sum;
      			path = tmp;
      		}
      		return;
      	} 
      	
      	for (int i = 0;i < pre[now].size();++i) {
      		tmp.push_back(pre[now][i]);
      		DFS(pre[now][i], sum + costs[now][pre[now][i]]);
      		tmp.pop_back();
      	} 
      }
      
      int main(void)
      {
      	scanf("%d %d %d %d", &n, &m, &s, &dest);
      	roads.resize(n, vector<int>(n, 0));
      	costs.resize(n, vector<int>(n, 0));
      	
      	for (int i = 0;i < m;++i) {
      		int city1 = 0, city2 = 0, dist = 0, cost = 0;
      		scanf("%d %d %d %d", &city1, &city2, &dist, &cost);
      		roads[city1][city2] = roads[city2][city1] = dist;
      		costs[city1][city2] = costs[city2][city1] = cost;
      	}
      	
      	Dijkstra(s);
      	tmp.push_back(dest);
      	DFS(dest, 0);
      	
      	for (int i = path.size() - 1;i >= 0;--i) printf("%d ", path[i]); 
      	printf("%d %d", d[dest], minCost);
      
          return 0;
      }
      
    2. 《算法笔记》P374

      “……只使用Dijkstra算法或是使用Dijkstra + DFS都是可以的。另外,本题很适合作为这两种方法的练手,建议读者都能练习一下写法。”


  4. A1072 Gas Station

    A gas station has to be built at such a location that the minimum distance between the station and any of the residential housing is as far away as possible. However it must guarantee that all the houses are in its service range.

    Now given the map of the city and several candidate locations for the gas station, you are supposed to give the best recommendation. If there are more than one solution, output the one with the smallest average distance to all the houses. If such a solution is still not unique, output the one with the smallest index number.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains 4 positive integers: N (≤103), the total number of houses; M (≤10), the total number of the candidate locations for the gas stations; K (≤104), the number of roads connecting the houses and the gas stations; and DS, the maximum service range of the gas station. It is hence assumed that all the houses are numbered from 1 to N, and all the candidate locations are numbered from G1 to GM.

    Then K lines follow, each describes a road in the format

    P1 P2 Dist
    

    where P1 and P2 are the two ends of a road which can be either house numbers or gas station numbers, and Dist is the integer length of the road.

    Output Specification:

    For each test case, print in the first line the index number of the best location. In the next line, print the minimum and the average distances between the solution and all the houses. The numbers in a line must be separated by a space and be accurate up to 1 decimal place. If the solution does not exist, simply output No Solution.

    Sample Input 1:
    4 3 11 5
    1 2 2
    1 4 2
    1 G1 4
    1 G2 3
    2 3 2
    2 G2 1
    3 4 2
    3 G3 2
    4 G1 3
    G2 G1 1
    G3 G2 2
    
    Sample Output 1:
    G1
    2.0 3.3
    
    Sample Input 2:
    2 1 2 10
    1 G1 9
    2 G1 20
    
    Sample Output 2:
    No Solution
    
    1. 我的

      #include <iostream>
      #include <vector>
      #include <algorithm>
      
      using namespace std;
      
      const int INF = 0x7fffffff;
      int n = 0, m = 0, k = 0, ds = 0;
      vector<vector<int>> roads;
      
      vector<int> d;
      void Dijkstra(int s)
      {
      	fill(d.begin(), d.end(), INF);
      	d[s] = 0;
      	vector<bool> visit(n + 1 + m, false);
      	
      	for (int i = 1;i <= n + m;++i) {
      		int u = -1, min = INF;
      		for (int j = 1;j <= n + m;++j) {
      			if (!visit[j] && d[j] < min) {
      				u = j;
      				min = d[j];
      			}
      		}
      		if (u == -1) return;
      		visit[u] = true;
      		for (int v = 1;v <= n + m;++v) {
      			if (!visit[v] && roads[u][v]) {
      				int newd = d[u] + roads[u][v];
      				if (d[v] > newd) d[v] = newd;
      			}
      		}
      	}
      }
      
      int main(void)
      {
      	scanf("%d %d %d %d", &n, &m, &k, &ds); 
      	roads.resize(n + 1 + m, vector<int>(n + 1 + m, 0));
      
      	for (int i = 0;i < k;++i) {
      		getchar();
      		int p1 = 0, p2 = 0, dist = 0;
      		
      		char c = getchar();
      		if (c != 'G') ungetc(c, stdin);
      		scanf("%d", &p1);
      		if (c == 'G') p1 += n;
      		getchar();
      		c = getchar();
      		if (c != 'G') ungetc(c, stdin);
      		scanf("%d", &p2);
      		if (c == 'G') p2 += n;
      		
      		scanf("%d", &dist);
      		roads[p1][p2] = roads[p2][p1] = dist;
      	}
      	
      	d.resize(n + m + 1, INF);
      	int minimum = 0, location = 0, minSum = INF;
      	for (int i = 1;i <= m;++i) {
      		Dijkstra(n + i);
      		
      		bool flag = false;
      		int sum = 0, tmp = INF;
      		for (int h = 1;h <= n;++h) {
      			if (d[h] > ds) {
      				flag = true;
      				break;
      			}
      			sum += d[h];
      			tmp = min(tmp, d[h]);
      		}
      		if (flag) continue;
      		
      		if (tmp > minimum) {
      			minimum = tmp;
      			location = i;
      			minSum = sum;
      		}
      		else if (tmp == minimum) {
      			if (sum < minSum) {
      				location = i;
      				minSum = sum;
      			}
      		}
      	}
      	if (location) printf("G%d\n%.1lf %.1lf", location, (double)minimum, (double)minSum / n);
      	else printf("No Solution");
      	
          return 0;
      }
      
    2. 《算法笔记》P381


  5. A1087 All Roads Lead to Rome

    Indeed there are many different tourist routes from our city to Rome. You are supposed to find your clients the route with the least cost while gaining the most happiness.

    Input Specification:

    Each input file contains one test case. For each case, the first line contains 2 positive integers N (2≤N≤200), the number of cities, and K, the total number of routes between pairs of cities; followed by the name of the starting city. The next N−1 lines each gives the name of a city and an integer that represents the happiness one can gain from that city, except the starting city. Then K lines follow, each describes a route between two cities in the format City1 City2 Cost. Here the name of a city is a string of 3 capital English letters, and the destination is always ROM which represents Rome.

    Output Specification:

    For each test case, we are supposed to find the route with the least cost. If such a route is not unique, the one with the maximum happiness will be recommanded. If such a route is still not unique, then we output the one with the maximum average happiness – it is guaranteed by the judge that such a solution exists and is unique

    Hence in the first line of output, you must print 4 numbers: the number of different routes with the least cost, the cost, the happiness, and the average happiness (take the integer part only) of the recommanded route. Then in the next line, you are supposed to print the route in the format City1->City2->...->ROM.

    Sample Input:
    6 7 HZH
    ROM 100
    PKN 40
    GDN 55
    PRS 95
    BLN 80
    ROM GDN 1
    BLN ROM 1
    HZH PKN 1
    PRS ROM 2
    BLN HZH 2
    PKN GDN 1
    HZH PRS 1
    
    Sample Output:
    3 3 195 97
    HZH->PRS->ROM
    
    1. 我的

      #include <iostream>
      #include <string>
      #include <vector>
      #include <map>
      #include <utility>
      
      using namespace std;
      
      const int INF = 0x7fffffff;
      string start = "";
      int n = 0, k = 0;
      map<string, int> happy, pathAmount, cityAmount, d, h;
      map<pair<string, string>, int> costs;
      map<string, string> pre;
      
      void Dijkstra(string s)
      {
      	map<string, bool> visit;
      	map<string, int>::iterator iter = happy.begin();
      	for (;iter != happy.end();++iter) {
      		pathAmount[iter->first] = 0;
      		cityAmount[iter->first] = 0;
      		d[iter->first] = INF;
      		h[iter->first] = 0;
      		visit[iter->first] = false;
      	}
          pathAmount[s] = 1;
      	d[s] = 0;
      	
      	for (int i = 0;i < n;++i) {
      		string u = "";
      		int min = INF;
      		for (iter = happy.begin();iter != happy.end();++iter) {
      			if (!visit[iter->first] && d[iter->first] < min) {
      				u = iter->first;
      				min = d[iter->first];
      			}
      		}
      		if (!i) u = s;
      		if (u == "") return;
      		visit[u] = true;
      		for (iter = happy.begin();iter != happy.end();++iter) {
      			if (!visit[iter->first] && costs[{u, iter->first}]) {
      				int newd = d[u] + costs[{u, iter->first}];
      				if (newd < d[iter->first]) {
      					d[iter->first] = newd;
      					h[iter->first] = h[u] + happy[iter->first];
      					pre[iter->first] = u;
      					pathAmount[iter->first] = pathAmount[u];
      					cityAmount[iter->first] = cityAmount[u] + 1;
      				}
      				else if (newd == d[iter->first]) {
      					int newh = h[u] + happy[iter->first];
      					if (newh > h[iter->first]) {
      						h[iter->first] = newh;
      						pre[iter->first] = u;
      						cityAmount[iter->first] = cityAmount[u] + 1;
      					}
      					else if (newh == h[iter->first]) {
      						int newCityAmount = cityAmount[u] + 1;
      						if (newh / newCityAmount > h[iter->first] / cityAmount[iter->first]) {
      							pre[iter->first] = u;
      							cityAmount[iter->first] = newCityAmount;
      						}
      					}
      					pathAmount[iter->first] += pathAmount[u];
      				}
      			}
      		}
      	}
      }
      
      int main(void)
      {
      	scanf("%d %d", &n, &k);
      	cin >> start;
      	
      	for (int i = 0;i < n - 1;++i) {
      		string city = "";
      		cin >> city;
      		int h = 0; 
      		scanf("%d", &happy[city]);
      	}
      	for (int i = 0;i < k;++i) {
      		string c1 = "", c2 = "";
      		cin >> c1 >> c2; 
      		int cost = 0;
      		scanf("%d", &cost);
      		costs[{c1, c2}] = costs[{c2, c1}] = cost;
      	}
      	
      	Dijkstra(start);
      	string end = "ROM";
      	printf("%d %d %d %d\n", pathAmount[end], d[end], h[end], h[end] / cityAmount[end]);
      	
      	vector<string> output; 
      	for (string now = end;now != start;output.push_back(now), now = pre[now]);
      	cout << start;
      	for (int i = output.size() - 1;i >= 0;--i) cout << "->" << output[i];
      	
          return 0;
      }
      

      newd < d[iter->first]是pathAmount[iter->first] = pathAmount[u]而不是pathAmount[iter->first] = 1

    2. 《算法笔记》P386

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MOOC PAT练习是指在在线课程平台上进行的编程能力考试。它提供了一系列编程题目,旨在帮助学生提高解决问题的能力和编程技能。下面是对此练习的回答: MOOC PAT练习是一种非常有益的学习资源。它可以帮助学生在虚拟的环境中解决实际问题,并通过编程来提高解决问题的能力。通过这种方式,学生可以更好地理解和掌握编程语言和算法知识。 MOOC PAT练习不仅可以提升学生的编程能力,还可以培养学生的创新思维和团队合作精神。在解决编程题目时,学生需要思考合适的算法和数据结构,同时还需要灵活运用编程语言来实现自己的想法。这样的练习可以锻炼学生的分析问题和解决问题的能力,培养其创新和合作意识。 通过MOOC PAT练习,学生可以接触到各种各样的编程题目,涵盖了不同的难度级别和主题领域。这对于学生来说是一个很好的学习机会,可以不断地挑战自己、提高自己。此外,该练习还提供了评测功能,学生可以实时了解自己的答题情况,并获得相应的反馈和建议,这有助于他们更好地调整学习进度和方向。 总结来说,MOOC PAT练习是一个非常有价值的学习资源,它可以提升学生的编程能力、培养创新和合作意识,并且通过不断挑战和实践来提高自己。对于想要学习编程的人来说,参加MOOC PAT练习是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值