L3-005 垃圾箱分布
分数 30
全屏浏览题目
切换布局
作者 陈越
单位 浙江大学
大家倒垃圾的时候,都希望垃圾箱距离自己比较近,但是谁都不愿意守着垃圾箱住。所以垃圾箱的位置必须选在到所有居民点的最短距离最长的地方,同时还要保证每个居民点都在距离它一个不太远的范围内。
现给定一个居民区的地图,以及若干垃圾箱的候选地点,请你推荐最合适的地点。如果解不唯一,则输出到所有居民点的平均距离最短的那个解。如果这样的解还是不唯一,则输出编号最小的地点。
输入格式:
输入第一行给出4个正整数:N(≤103)是居民点的个数;M(≤10)是垃圾箱候选地点的个数;K(≤104)是居民点和垃圾箱候选地点之间的道路的条数;DS是居民点与垃圾箱之间不能超过的最大距离。所有的居民点从1到N编号,所有的垃圾箱候选地点从G1到GM编号。
随后K行,每行按下列格式描述一条道路:
P1 P2 Dist
其中P1
和P2
是道路两端点的编号,端点可以是居民点,也可以是垃圾箱候选点。Dist
是道路的长度,是一个正整数。
输出格式:
首先在第一行输出最佳候选地点的编号。然后在第二行输出该地点到所有居民点的最小距离和平均距离。数字间以空格分隔,保留小数点后1位。如果解不存在,则输出No Solution
。
输入样例1:
4 3 11 5
1 2 2
1 4 2
1 G1 4
1 G2 3
2 3 2
2 G2 1
3 4 2
3 G3 2
4 G1 3
G2 G1 1
G3 G2 2
输出样例1:
G1
2.0 3.3
输入样例2:
2 1 2 10
1 G1 9
2 G1 20
输出样例2:
No Solution
今天来点ex图论,dijkstra(),源于我两天都因为读入寄了,t m d,ysu的llh佬交了我stoi()是将字符串转化为数字,to_string()可以将数字转化成字符串,然后s.find("")!=string::npos就是说明可以找到这个字符。剩下的就简单了,就是最短路筛选。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=20010;
const int M=1015;
#define x first
#define y second
int n,m,k,ds;
int idx=0,e[N],ne[N],h[N],w[N],dist[M],minn[N];
double avg[N];
void add(int a,int b,int c){
e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
bool st[M];
typedef pair<int,int> PII;
unordered_map<string,int> mp;
vector<int> ans;
void dijkstra(int root){
double ans=0;
memset(st,false,sizeof st);
memset(dist,0x3f,sizeof dist);
priority_queue<PII,vector<PII>,greater<PII>> heap;
heap.push({0,root});
dist[root]=0;
while(heap.size()){
PII t=heap.top();
heap.pop();
int ver=t.y,distance=t.x;
if(st[ver]) continue;
st[ver]=true;
for(int i=h[ver];~i;i=ne[i]){
int j=e[i];
if(dist[j]>distance+w[i]){
dist[j]=distance+w[i];
heap.push({dist[j],j});
}
}
}
for(int i=1;i<=n;i++){
if(dist[i]<=ds){
minn[root]=min(minn[root],dist[i]);
ans+=dist[i];
}
else minn[root]=-1;
}
avg[root]=double(ans)/n;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m>>k>>ds;
memset(h,-1,sizeof h);
for(int i=1;i<=m;i++) mp["G"+to_string(i)]=n+i;
int cnt=n+m;
while(k--){
string be,en;
int d;
cin>>be>>en>>d;
int a,b;
if(be.find("G")!=string::npos) a=mp[be];
else a=stoi(be);
if(en.find("G")!=string::npos) b=mp[en];
else b=stoi(en);
add(a,b,d);
add(b,a,d);
}
memset(minn,0x3f,sizeof minn);
for(int i=n+1;i<=cnt;i++){
dijkstra(i);
}
int mm=0;
for(int i=n+1;i<=cnt;i++) mm=max(minn[i],mm);
if(mm==0) cout<<"No Solution";
else{
for(int i=n+1;i<=cnt;i++) if(minn[i]==mm) ans.push_back(i);
sort(ans.begin(),ans.end());
double av=1e9;
for(int i=0;i<ans.size();i++) av=min(av,avg[ans[i]]);
for(int i=0;i<ans.size();i++){
if(avg[ans[i]]==av){
cout<<'G'<<ans[i]-n<<endl;
printf("%.1lf %.1lf",double(minn[ans[i]]),avg[ans[i]]);
break;
}
}
}
return 0;
}
天梯赛不留遗憾,加油!