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 ;
}