Dijkstra
# include <iostream>
# include <algorithm>
# include <numeric>
# include <vector>
# include <set>
using namespace std;
const int MAXV = 1020;
const int INF = 0xffffff;
struct Node{
int v, dis;};
int N, M, K, Ds;
vector<Node> G[MAXV];
set<int> gasStation;
int dist[MAXV];
bool vis[MAXV];
int getID(string S){
return S[0] == 'G' ? N + stoi(S.substr(1)) : stoi(S);
}
void Dijkstra(int s){
fill(dist, end(dist), INF);
fill(vis, end(vis), false);
dist[s] = 0;
for(int i = 1;i <= N+M;++i){
int u = -1;
int MIN = INF;
for(int j = 1;j <= N+M;++j){
if(vis[j] == false && dist[j] < MIN){
u = j;
MIN = dist[j];
}
}
if(u == -1) return;
vis[u] = true;
for(Node next: G[u]){
int v = next.v, uv_dis = next.dis;
if(vis[v] == false){
if(dist[u] + uv_dis < dist[v]){
dist[v] = dist[u] + uv_dis;
}
}
}
}
}
int main(){
cin >> N >> M >> K >> Ds;
for(int i = 0;i < K;++i){
string SID1, SID2;
int Dist;
cin >> SID1 >> SID2 >> Dist;
int ID1 = getID(SID1);
int ID2 = getID(SID2);
if(ID1 > N) gasStation.insert(ID1);
if(ID2 > N) gasStation.insert(ID2);
G[ID1].push_back({
ID2, Dist});
G[ID2].push_back({
ID1, Dist});
}
int minStation = -1;
double maxDist = -1;
double minAvg = INF;
for(int station: gasStation){
Dijkstra(station);
int flag = 0;
double dis = INF, avg = 0.0;
for(int j = 1;j <= N;++j){
if(dist[j] > Ds){
flag = -1;
break;
}
if(dist[j] < dis) dis = dist[j];
avg += 1.0*dist[j] / N;
}
if(flag == -1) continue;
if(dis > maxDist){
maxDist = dis;
minAvg = avg;
minStation = station;
}
else
if(dis == maxDist){
if(avg < minAvg){
minAvg = avg;
minStation = station;
}
}
}
if(minStation == -1) {
cout << "No Solution\n";
}
else {
cout << "G" << minStation - N << endl;
printf("%.1f %.1f\n", maxDist, minAvg);
}
return 0;
}