题目
题目描述
A gas station has
to be built
at such
a location that
the minimum distance between
the station
and any of the residential housing is
as far away
as possible. However
it must guarantee that all
the houses are
in its service range.
Now given
the map
of the city
and several candidate locations
for the gas station, you are supposed
to give
the best recommendation. If there are more than
one solution, output
the one with the smallest
average distance
to all
the houses. If such
a solution is still
not unique, output
the one with the smallest index
number.
输入描述:
Each input
file contains one test
case. For
each case,
the first line contains 4 positive integers: N (<=
103),
the total
number of houses; M (<=
10),
the total
number of the candidate locations
for the gas stations; K (<=
104),
the number of roads connecting
the houses
and the gas stations;
and DS,
the maximum service range
of the gas station. It is hence assumed that all
the houses are numbered
from 1 to N,
and all
the candidate locations are numbered
from G1
to GM.
Then K
lines follow,
each describes
a road
in the format
P1 P2 Dist
where P1
and P2 are
the two ends of a road which can be either house numbers
or gas station numbers,
and Dist is
the integer length of the road.
输出描述:
For
each test
case, print
in the first line the index
number of the best location. In
the next
line, print
the minimum
and the average distances between
the solution
and all
the houses. The numbers
in a line must be separated
by a space and be accurate up
to 1 decimal place. If
the solution does
not exist, simply output “No Solution”.
输入例子:
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
输出例子:
G1
2.0 3.3
解题思路
1.题目的意思是要满足到住宅区的最小的距离最大,如果存在多个最小的值,则取平均值最大的,如果还是相等,则取序号较小的Gas Station。2.算出每个加油站到所有的住宅区的最短路径就可以了(我这里用Dijkstra算法求最短路径),然后再比较就可以了。3.sstream中的stringstream可以将string类型的变量转化为其他类型的,这里利用比较方便。4.对于判断输出,即可利用满足tem_min>index_min或者满足tem_min==index_min&&tem_sum<index_sum就更新index,index_min,index_sum,并且这里从前往后判断,所以能保证前俩项都相同的情况下,取到的是序号较小的。这里我们可以想到设置初始值index=-1,index_min=0,index_sum=INT_MAX。
我出错的一些点
1.Dijkstra算法中dist[k]+a[k][i]<dist[i],其中将disk[k]和a[k][i]中最大值设为INT_MAX,最后溢出了,害死我了。2.**对Dijkstra算法不熟悉,此算法的总体思路就是,访问改点并将改点标记为访问,遍历改点领域,借助该点更新Dist[i],并在领域中找到值最小且没有被访问过的点递归访问改点,直到所有点都访问完了就return。**ps,非递归的思路可以看这个非递归Dijkstra算法3.//要加double,setprecision才会起效果! cout << fixed << setprecision(1) << (double)index_min << " " << index_sum / (double)n << endl;
代码
#include <iostream>
#include<string>
#include<sstream>
#include<vector>
#include<iomanip>
#define MAX 10000
using namespace std;
int n, m, k, ds;
int a[
1000 +
10 +
5][
1000 +
10 +
5];
int dist[
1000 +
10 +
5];
int pre[
1000 +
10 +
5];
bool visited[
1000 +
10 +
5];
int str2int(
string a)
{
int b;
if (a[
0] ==
'G')
{
string tem_a = a.substr(
1);
stringstream ss;
ss << tem_a;
ss >> b;
b += n;
return b;
}
else
{
stringstream ss;
ss << a;
ss >> b;
return b;
}
}
void init(
int k)
{
for (
int i =
1; i <= n + m; i++)
{
dist[i] =
100;
visited[i] =
false;
pre[i] = -
1;
}
dist[k] =
0;
}
void Dijkstra(
int k)
{
if (k ==
0)
return;
visited[k] =
true;
int min = MAX,k1=
0;
for (
int i =
1; i <= n+m; i++)
{
if (dist[k]+a[k][i]<dist[i])
{
dist[i] = dist[k] + a[k][i];
pre[i] = k;
}
if (dist[i]<min&&!visited[i])
{
k1 = i;
min = dist[i];
}
}
Dijkstra(k1);
}
int main()
{
cin >> n >> m >> k >> ds;
for (
int i =
1; i <= n + m; i++)
{
for (
int j =
1; j <= n + m; j++)
{
if (i == j)
{
a[i][j] =
0;
}
else
{
a[i][j] = MAX;
}
}
}
string tem_a, tem_b;
int tem_c;
int d1, d2;
for (
int i =
0; i < k; i++)
{
cin >> tem_a >> tem_b >> tem_c;
d1 = str2int(tem_a);
d2 = str2int(tem_b);
a[d1][d2] = tem_c;
a[d2][d1] = tem_c;
}
int index=-
1, index_min=
0, index_sum=MAX;
for (
int i=n+
1; i <= n+m; i++)
{
init(i);
Dijkstra(i);
int tem_sum =
0, tem_submin = MAX;
bool flag =
false;
for (
int j =
1; j <= n; j++)
{
if (dist[j]>ds)
{
flag =
true;
break;
}
if (dist[j]<tem_submin)
{
tem_submin = dist[j];
}
tem_sum += dist[j];
}
if (flag)
continue;
if (tem_submin>index_min||(tem_submin==index_min&&index_sum>tem_sum))
{
index = i;
index_min = tem_submin;
index_sum = tem_sum;
}
}
if (index==-
1)
{
cout <<
"No Solution" << endl;
}
else
{
cout <<
"G" << index - n << endl;
cout << fixed << setprecision(
1) << (
double)index_min <<
" " << index_sum / (
double)n << endl;
}
return 0;
}
转载请注明原文地址: https://ju.6miu.com/read-1312024.html