版权声明:转载请注明出处,谢谢。 https://blog.csdn.net/Mercury_Lc/article/details/88798943
7-1 垃圾箱分布 (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
&:将垃圾箱看做也是一些点,和居民点共同组成图,然后以每个垃圾箱为起点跑最短路,枚举 dist[ ] 数组,符合条件的保留。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 10005; const int inf = 0x3f3f3f3f; int a[maxn][maxn]; int dist[maxn]; int vis[maxn]; int n,m,k,d; int fin(string s){ int i,ans,f; i = 0; ans = 0; f = 0; if(s[0] == 'G') i ++,f = n; int len = s.length(); for(; i < len; i ++) ans = ans * 10 + (s[i] - '0'); return (ans + f); } void dijkstra(int s){ for(int i = 0; i <= n + m; i ++){ dist[i] = a[s][i]; vis[i] = 0; } int Min = inf; int v = s; for(int i = 0; i < n + m ; i ++){ Min = inf; v = s; for(int j = 1; j <= n + m; j ++){ if(!vis[j] && dist[j] < Min){ Min = dist[j]; v = j; } } vis[v] = 1; for(int j = 1; j <= n + m; j ++){ if(!vis[j] && dist[j] > dist[v] + a[v][j]){ dist[j] = dist[v] + a[v][j]; } } } } int main() { ios::sync_with_stdio(0); cin >> n >> m >> k >> d; for(int i = 0; i <= n + m; i ++){ for(int j = 0; j <= n + m; j ++){ if(i != j) a[i][j] = inf; else a[i][j] = 0; } } string u,v; int w; for(int i = 0; i < k; i ++){ cin >> u >> v >> w; a[fin(u)][fin(v)] = a[fin(v)][fin(u)] = w; // cout << u << " " << v << " " << fin(u) << " " << fin(v) << " " << "******** *" << endl; } int Min = 0, minn,idx = 0; double ans = 0, res; bool flag, F = false; for(int i = n + 1; i <= n + m; i ++){ dijkstra(i); flag = false; minn = inf; res = 0; for(int j = 1; j <= n; j ++){ if(dist[j] > d){ flag = true; break; } else { minn = min(minn,dist[j]); res += dist[j]; } } if(!flag){ if(minn > Min){ Min = minn; ans = res; idx = i; }else if(minn == Min){ if(ans > res){ ans = res; idx = i; } } F = true; } } if(F)printf("G%d\n%.1lf %.1lf\n",idx - n, (double)Min, ans / (double) n); else printf("No Solution\n"); return 0; }