PAT A1072 Gas Station Precautions

Topic link → https://pintia.cn/problem-sets/994805342720868352/problems/994805396953219072

Note 1: Gas station number processing

  • The wrong case, ignoring that the number of the gas station can be 10, took a long time to find it. Be sure to read the title carefully!
int getId(string s) {
    
    	//将编号转化为整数(数组下标) 
	if (s[0] == 'G') {
    
    
		return n + s[1] - '0';
	} else {
    
    
		return stoi(s);
	}
}
  • Correct (it is more convenient to use the stoi function)

    int getId(string s) {
          
          	// 将字符串转化为整数(数组下标)
    	if (s[0] == 'G') {
          
          		// 加油站
    		return n + stoi(s.substr(1));	// G后面的数字
    	} else {
          
          
    		return stoi(s);	
    	}
    }
    

Note 2: Average Calculation

Try not to add all numbers together and then average, overflow may occur.

avg += 1.0 * d[i] / n;	// 在运算过程中计算平均值

Attention 3

The problem needs to use the Dijskra algorithm multiple times, and each time the algorithm is run, an initial value must be assigned to the vis array (marking whether the vertex is visited).

AC code

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXV = 1030, INF = 1000000000;
bool vis[MAXV];
int G[MAXV][MAXV], d[MAXV], n, m, k, Ds;

void Dijskra(int s) {
    
    	//求s到其他所有顶点的最短路径
	memset(vis, 0, sizeof(vis));
	fill(d, d + MAXV, INF);
	d[s] = 0;
	for (int i = 0; i < n + m; i++) {
    
    	//n + m个顶点, 循环次数
		int u = -1, MIN = INF;
		for (int j = 1; j <= n + m; j++) {
    
    	// 寻找最小值
			if (vis[j] == false && d[j] < MIN) {
    
    
				MIN = d[j];
				u = j;
			}
		}
		if (u == -1) return; 	//图不连通
		vis[u] = true;
		for (int v = 1; v <= n + m; v++) {
    
    	// 更新 d 数组
			if (vis[v] == false && d[u] + G[u][v] < d[v]) {
    
    
				d[v] = d[u] + G[u][v];
			}
		}
	}
}

int getId(string s) {
    
    	// 将字符串转化为整数(数组下标)
	if (s[0] == 'G') {
    
    
		return n + stoi(s.substr(1));
	} else {
    
    
		return stoi(s);
	}
}

int main() {
    
    
	cin >> n >> m >> k >> Ds;
	int u, v, w;
	string s, t;
	fill(G[0], G[0] + MAXV * MAXV, INF);	// 无穷大表示不可达
	for (int i = 0; i < k; i++) {
    
    
		cin >> s >> t >> w;
		u = getId(s), v = getId(t);
		G[u][v] = G[v][u] = w;
	}

	int ansId = -1, minDis;
	double ansAvg = INF, avg, ansDis = -1;
	for (int v = n + 1; v <= n + m; v++) {
    
    
		Dijskra(v);
		avg = 0.0, minDis = INF;
		for (int i = 1; i <= n; i++) {
    
    
			if (d[i] > Ds) {
    
    
				minDis = -1;
				break;
			}
			if(d[i] < minDis) minDis = d[i];
			avg += 1.0 * d[i] / n;
		}
		if (minDis == -1) continue;	//该加油站不满足条件, 距离村庄的距离超过界限
		if (minDis > ansDis || (minDis == ansDis && avg < ansAvg)) {
    
    	// 平均距离更小, 或平均距离相同但 最小距离较远
			ansDis = minDis;
			ansId = v - n;
			ansAvg = avg;
		}
	}

	if (ansId == -1) {
    
    
		cout << "No Solution";
	} else {
    
    
		printf("G%d\n%.1lf %.1lf", ansId, ansDis, ansAvg);
	}

	return 0;
}

Guess you like

Origin blog.csdn.net/VariatioZbw/article/details/122862720