【1072 30 Dijkstra】 Gas Station
传送门
题意
给定\(n\)个居民地,\(m\)个候选加油站,\(k\)条边,\(d_{s}\)为居民地到加油站的最大距离,选出一个加油站满足到所有居民地的距离小于\(d_{s}\),其到居民地的最短距离是所有中最大的,如果相同选取到所有居民地平均距离最小的,再相同选取\(id\)小的
数据范围
\(n\leq 1000\)
\(m\leq 10\)
\(k\leq 10^{4}\)
题解
- 加油站到居民地可以途径候选加油站
- 暴力以每个加油站为起点求到所有点的最短路
- 统计\(min,average\),更新答案
Code
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
const int INF=0x3f3f3f3f,N=1030;
map<string,int>mp;
map<int,string>ump;
int n,m,k,ds,d[N],g[N][N];
bool st[N];
void dijkjstra(int gas){
memset(d,0x3f,sizeof d);
memset(st,0,sizeof st);
d[gas]=0;
for(int i=0;i<n+m;i++){
int t=-1;
for(int j=1;j<=n+m;j++)
if(!st[j] && (t==-1 || d[t]>d[j])) t=j;
if(t==-1) return;
st[t]=1;
for(int j=1;j<=n+m;j++)
if(!st[j] && g[t][j]!=INF && d[j]>d[t]+g[t][j])
d[j]=d[t]+g[t][j];
}
}
int main(){
memset(g,0x3f,sizeof g);
scanf("%d%d%d%d",&n,&m,&k,&ds);
string x="G";
for(int i=1;i<=n;i++) {string t=to_string(i);mp[t]=i;}
for(int i=1;i<=m;i++)
{x+=to_string(i); mp[x]=n+i; ump[n+i]=x; x="G"; }
for(int i=0;i<k;i++){
int dis; string a,b; cin>>a>>b; scanf("%d",&dis);
int u=mp[a],v=mp[b];
g[u][v]=g[v][u]=dis;
}
int id=-1;
double minmax=-1,min_avg=INF;
for(int i=n+1;i<=m+n;i++) {
double avg=0,mi = INF;
dijkjstra(i);
for(int i=1;i<=n;i++) {
if(d[i] > ds) {mi=-1;break;}
if(d[i]<mi) mi=d[i];
avg += 1.0*d[i];
}
if(mi==-1) continue;
avg = avg/n;
if(mi > minmax) {
minmax=mi;
min_avg=avg;
id=i;
}
else if(mi == minmax && avg < min_avg){
min_avg=avg;
id=i;
}
}
if(id!=-1)
printf("%s\n%.1lf %.1lf",ump[id].c_str(),minmax, min_avg);
else printf("No Solution");
}

浙公网安备 33010602011771号