1072 Gas Station (30分)(最短路)
思路:因为 m m m很小,所以暴力枚举点跑最短路,取最值即可。
吐槽:样例1的输出是错的,应该是 3.2 3.2 3.2而不是 3.3 3.3 3.3,就是保留一位,我还以为是四舍五入,导致一直 W A WA WA最后一个点。
我已经发了邮件给
P
A
T
PAT
PAT。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
struct edge{
int to,nt;double w;
}e[M];
double d[N];
int n,m,k,cnt,h[N],vis[N];
double D;
void add(int u,int v,double w){
e[++cnt]={v,h[u],w},h[u]=cnt;
e[++cnt]={u,h[v],w},h[v]=cnt;
}
inline int read(){
char a[10];
scanf("%s",a);
int la=strlen(a),s=0;
if(a[0]=='G') {
for(int i=1;i<la;i++) s=s*10+a[i]-'0';
s+=n;
}
else {
for(int i=0;i<la;i++) s=s*10+a[i]-'0';
}
return s;
}
void spfa(int st){
queue<int>q;
for(int i=1;i<=n+m;i++) d[i]=1e15;d[st]=0;
mst(vis,0);
q.push(st),vis[st]=1;
while(!q.empty()){
int u=q.front();q.pop();vis[u]=0;
for(int i=h[u];i;i=e[i].nt){
int v=e[i].to;double w=e[i].w;
if(d[v]>d[u]+w){
d[v]=d[u]+w;
if(!vis[v]) q.push(v),vis[v]=1;
}
}
}
}
int main(){
scanf("%d%d%d%lf",&n,&m,&k,&D);
for(int i=1,u,v;i<=k;i++){
u=read(),v=read();double w;scanf("%lf",&w);
add(u,v,w);
}
int id=-1;double a1=0,a2=1e15;
for(int i=n+1;i<=n+m;i++){
spfa(i);
double mn=1e15,ave=0;
bool f=1;
for(int j=1;j<=n;j++){
if(d[j]>D){
f=0;break;
}
mn=min(mn,d[j]);
ave+=d[j];
}
if(!f) continue;
if(mn>a1){
id=i-n,a1=mn,a2=ave;
}
else if(mn==a1&&ave<a2){
id=i-n,a2=ave;
}
}
if(id==-1) puts("No Solution");
else printf("G%d\n%.1f %.1f\n",id,a1,a2/n);
return 0;
}