其实归根到底,就是一个Dijkstra的应用。我的做法不够简单,或者说相当繁琐。我是把问题想复杂了,因为题目要处理加油站的名字,所以我是用了一大堆map和vector,甚至还用了指针数组。注意visit数组在读取输入时是用来记录有没有重复push加油站的……其实稍微处理一下就可以非常简单,网上很多大神比我的程序至少少三分之一……
#include <iostream> #include <vector> #include <algorithm> #include <map> #include <string> #define Infinity 999999999 using namespace std; struct station{ int id; double mindist; double avg; station (int id,double mindist,double avg):id(id),mindist(mindist),avg(avg){} }; map<string,int>Stoi; map<int,string>Itos; vector<int>gas; int N,M,K,Ds,idnum=1,r=0; int G[1020][1020],dist[1020]; bool visit[1020]; station *sta[20]; int convert(const string s) { if(Stoi[s]==0) { Stoi[s]=idnum; Itos[idnum]=s; return idnum++; } else return Stoi[s]; } bool IsGasStation(int u) { string temp=Itos[u]; if(temp[0]=='G')return true; else return false; } int comp(station *p1,station *p2) { if(p1->mindist!=p2->mindist)return p1->mindist>p2->mindist; if(p1->avg!=p2->avg)return p1->avg<p2->avg; return Itos[p1->id]<Itos[p2->id]; } int main() { fill(G[0],G[0]+1020*1020,Infinity); fill(visit,visit+1020,false); cin>>N>>M>>K>>Ds; for(int i=0;i<K;i++) { string p1,p2; int c1,c2; cin>>p1>>p2; c1=convert(p1); if(p1[0]=='G'&&visit[c1]==false) { gas.push_back(c1); visit[c1]=true; } c2=convert(p2); if(p2[0]=='G'&&visit[c2]==false) { gas.push_back(c2); visit[c2]=true; } cin>>G[c1][c2]; G[c2][c1]=G[c1][c2]; } for(vector<int>::iterator p=gas.begin();p!=gas.end();p++) { fill(visit,visit+1020,false); fill(dist,dist+1020,Infinity); dist[*p]=0; while(true) { int u=-1,min=Infinity; for(int i=1;i<=N+M;i++) { if (!visit[i] && dist[i] < min ) { min = dist[i]; u = i; } } if(u==-1)break; visit[u]=true; for(int v=1;v<=N+M;v++) { if(visit[v]==false&&G[u][v]!=Infinity) { if(G[u][v]+dist[u]<dist[v]) { dist[v]=G[u][v]+dist[u]; } } } } double min=Infinity,avg=0.0; for(int i=1;i<=N+M;i++) { if(!IsGasStation(i)) { if(dist[i]>Ds) { sta[r++]=new station(*p,-1,Infinity); min=-1; break; } else { if(dist[i]<min)min=dist[i]; avg+=1.0*dist[i]; } } } if(min!=-1) { sta[r++]=new station(*p,min,avg/N); } } sort(sta,sta+r,comp); double min=sta[0]->mindist; if(min==-1) { cout<<"No Solution"; return 0; } cout<<Itos[sta[0]->id]<<endl; printf("%.1f %.1f",sta[0]->mindist,sta[0]->avg); }