この質問には多くの落とし穴があります
。1。入力はG1G110である可能性があります。2を除外する必要があります
。入力には、G1 G2 10、G1 G21などの複数のパスが含まれる場合があります。最小値を維持する必要があります
。3 。ガソリンスタンドの番号はG103文字に達し、住宅の建物番号は1000の4文字に達する可能性があります。サンプルを見ると、1つの番号と間違えます。
コード:
#include <cstdio>
#include <climits>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxv = 1010;
const int INF = INT_MAX;
int N, M, V, K, Ds;
int graph[maxv][maxv];
int d[maxv];
bool confirmed[maxv];
int f_index=-1;
double f_min=0.0, f_ave=INF;
int change(char a[]);
void dijkstra(int s);
int main(){
scanf("%d%d%d%d", &N, &M, &K, &Ds);
V = N + M;
fill(graph[0], graph[0]+maxv*maxv, INF);
while(K--){
char p1[5], p2[5];
int dist;
scanf("%s%s%d", p1, p2, &dist);
int v1 = change(p1);
int v2 = change(p2);
if(v1==v2) continue;
if(dist<graph[v1][v2]){
graph[v1][v2] = graph[v2][v1] = dist;
}
}
for(int i=0; i<M; i++){
dijkstra(i);
double sum=0.0, t_ave, t_min=INF;
bool solution = true;
for(int j=M; j<V; j++){
if(d[j]>Ds){
solution = false;
break;
}
sum += d[j];
if(d[j]<t_min) t_min = d[j];
}
if(!solution) continue;
else{
t_ave = sum / N;
if(t_min>f_min || (t_min==f_min && t_ave<f_ave)){
f_min = t_min;
f_ave = t_ave;
f_index = i;
}
}
}
if(f_index==-1) printf("No Solution");
else printf("G%d\n%.1f %.1f", f_index+1, f_min, round(f_ave*10)/10);
return 0;
}
int change(char a[]){
if(a[0]=='G'){
if(strlen(a)==3) return 9;
else return a[1]-'1'; //加油站编号 0 ~ M-1
}
else{
int n;
sscanf(a, "%d", &n);
return n-1+M; //居民楼编号 M ~ V-1
}
}
void dijkstra(int s){
fill(d, d+V, INF);
fill(confirmed, confirmed+V, 0);
d[s] = 0;
for(int k=0; k<V; k++){
int u=-1, min_d=INF;
for(int i=0; i<V; i++){
if(!confirmed[i] && d[i]<min_d){
u = i;
min_d = d[i];
}
}
if(u==-1) return;
confirmed[u] = true;
for(int j=0; j<V; j++){
//u->j
if(!confirmed[j] && graph[u][j]!=INF){
if(d[u]+graph[u][j]<d[j]){
d[j] = d[u] + graph[u][j];
}
}
}
}
return;
}