My personal station: acking-you.github.io

subject
Topic translation
First look at this topic to know: all roads lead to Rome
Word accumulation
Indeed In fact, indeed routes Route recommended Highly respected # example sentence Indeed there are many different tourist routes from our city to Rome. # translate In fact, there are many different routes from our city to Rome.
Title Description
original text
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.
translate
In fact, there are many different routes from our city to Rome. You should find a route for your guests to spend the least and get the most happiness.
Enter description
original text
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.
translate
For each test case, the first line contains two positive integers:
N. Represents the number of cities. K. Represents the total number of roads between any two cities.
Starting city represents the city where the start is located. Next, N-1 lines, each line gives the name of the city and the happiness value you can get to the city (the first city has no happiness value).
Next, K lines are used to describe a road between two cities in the format of "city1 city2 cost", indicating the names of the two cities and the cost required for the road between them. The city names here are expressed in English words of what length, and ROM stands for Rome.
Output description
original text
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 recommended route. Then in the next line, you are supposed to print the route in the format "City1->City2->...->ROM".
translate
In the first line, you must print four numbers: 1. The number of different routes with the minimum cost, 2. The corresponding minimum cost, 3. The corresponding maximum happiness, and 4. The average happiness.
The second line prints the travel route.
Problem solving analysis
This topic is the same as the previous PAT topic: Emergency As like as two peas. Both calculate the number of edge weights and the maximum value of the simultaneous point weight to ensure the minimum edge weight. The part that needs special processing is that it does not directly enter the number, but describes the city in the form of string. Therefore, before we write Dijkstra algorithm, we first map the string and number, then the normal Dijkstra algorithm, and finally print the path through path.
Detailed explanation of problem solving code
Parameters required by the topic
//Enter the required data int N,K; string start; unordered_map<string,int>check1; const char* check2[MaxN]; int points[MaxN]; //Data needed to update answers int nums[MaxN];//Record the shortest path to a node int w[MaxN];//Record the maximum value of the midpoint weight of the shortest path //Parameters required by Dij algorithm int path[MaxN]; int dist[MaxN]; bitset<MaxN> visit;
Input module
void Input(){ ios::sync_with_stdio(false); memset(head,0xff,sizeof(head)); memset(dist,0x3f,sizeof(dist)); cin>>N>>K>>start; check2[0] = start.c_str(); for(int i=1;i<N;i++){ string* x = new string; //The heap memory must be used, or the memory will be destroyed automatically once the range ends, and there is no data in the memory pointed to by the check2 pointer int point; cin>>(*x)>>point; check2[i] = x->c_str(); points[i] = point; check1[(*x)] = i; } for (int i = 0; i < K; ++i){ string x,y;int len;cin>>x>>y>>len; int a = check1[x],b = check1[y]; add(a,b,len); add(b,a,len); } }
Chain forward star construction map
//Data and operations required for drawing construction int tot = 0; int head[MaxN]; struct{ int to; int len; int next; }edge[MaxN*MaxN]; void add(int a,int b,int len){ edge[tot].to = b; edge[tot].len = len; edge[tot].next = head[a]; head[a] = tot++; }
Operation of Dij algorithm
//Dij operation int findMin() { int minV = 0; int cmp = INF; for (int i = 1; i < N; i++) { if (!visit[i] && dist[i] < cmp) { cmp = dist[i]; minV = i; } } visit[minV] = 1; return minV; } void Dij() { for (int i = 0; i < N; i++) { int node = findMin(); if (node == 0) break; for (int i = head[node]; i != -1; i = edge[i].next) { if (!visit[edge[i].to]) { if (dist[edge[i].to] > edge[i].len + dist[node]) { dist[edge[i].to] = edge[i].len + dist[node]; path[edge[i].to] = node; nums[edge[i].to] = nums[node]; w[edge[i].to] = w[node] + points[edge[i].to]; } else if (dist[edge[i].to] == edge[i].len + dist[node]) { nums[edge[i].to] += nums[node]; if (w[edge[i].to] < w[node] + points[edge[i].to]) { w[edge[i].to] = w[node] + points[edge[i].to]; path[edge[i].to] = node; } } } } } }
print operation
// Print operation, using stack to realize LIFO void print() { vector<int>St; string end = "ROM"; int ed = check1[end]; int cnt = 1; int next = path[ed]; while (next) { St.push_back(next); cnt++; next = path[next]; } int happiness = w[ed]; int average = happiness / cnt; cout << nums[ed] << ' ' << dist[ed] << ' ' << happiness << ' ' << average << '\n'; cout << start; while (!St.empty()) { cout << "->" << check2[St.back()]; St.pop_back(); } cout << "->" << end; }
Integrate the code to get the answer
Fairly efficient
My answer:
#include<bits/stdc++.h> using namespace std; #define MaxN 202 #define INF 0x3f3f3f3f //Enter the required data int N, K; string start; unordered_map<string, int>check1; const char* check2[MaxN]; int points[MaxN]; //Data needed to update answers int nums[MaxN];//Record the shortest path to a node int w[MaxN];//Record the maximum value of the midpoint weight of the shortest path //Parameters required by Dij algorithm int path[MaxN]; int dist[MaxN]; bitset<MaxN> visit; //Data required for mapping int tot = 0; int head[MaxN]; struct { int to; int len; int next; } edge[MaxN * MaxN]; void add(int a, int b, int len) { edge[tot].to = b; edge[tot].len = len; edge[tot].next = head[a]; head[a] = tot++; } void Input() { ios::sync_with_stdio(false); memset(head, 0xff, sizeof(head)); memset(dist, 0x3f, sizeof(dist)); cin >> N >> K >> start; check2[0] = start.c_str(); for (int i = 1; i < N; i++) { string* x = new string; //The heap memory must be used, or the memory will be destroyed automatically once the range ends, and there is no data in the memory pointed to by the check2 pointer int point; cin >> (*x) >> point; check2[i] = x->c_str(); points[i] = point; check1[(*x)] = i; } for (int i = 0; i < K; ++i) { string x, y; int len; cin >> x >> y >> len; int a = check1[x], b = check1[y]; add(a, b, len); add(b, a, len); } } //Dij operation int findMin() { int minV = 0; int cmp = INF; for (int i = 1; i < N; i++) { if (!visit[i] && dist[i] < cmp) { cmp = dist[i]; minV = i; } } visit[minV] = 1; return minV; } void Dij() { for (int i = 0; i < N; i++) { int node = findMin(); if (node == 0) break; for (int i = head[node]; i != -1; i = edge[i].next) { if (!visit[edge[i].to]) { if (dist[edge[i].to] > edge[i].len + dist[node]) { dist[edge[i].to] = edge[i].len + dist[node]; path[edge[i].to] = node; nums[edge[i].to] = nums[node]; w[edge[i].to] = w[node] + points[edge[i].to]; } else if (dist[edge[i].to] == edge[i].len + dist[node]) { nums[edge[i].to] += nums[node]; if (w[edge[i].to] < w[node] + points[edge[i].to]) { w[edge[i].to] = w[node] + points[edge[i].to]; path[edge[i].to] = node; } } } } } } // Print operation, using stack to realize LIFO void print() { vector<int>St; string end = "ROM"; int ed = check1[end]; int cnt = 1; int next = path[ed]; while (next) { St.push_back(next); cnt++; next = path[next]; } int happiness = w[ed]; int average = happiness / cnt; cout << nums[ed] << ' ' << dist[ed] << ' ' << happiness << ' ' << average << '\n'; cout << start; while (!St.empty()) { cout << "->" << check2[St.back()]; St.pop_back(); } cout << "->" << end; } int main() { Input(); //First Dij processing dist[0] = 0; nums[0] = 1; for (int i = head[0]; i != -1; i = edge[i].next) { dist[edge[i].to] = edge[i].len; w[edge[i].to] = points[edge[i].to]; nums[edge[i].to] = nums[0]; } Dij(); print(); return 0; }