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
1072 Gas Station (30分)(最短路)_最短路

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