版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GYH0730/article/details/82867040
题目链接:https://cn.vjudge.net/problem/Gym-100851F
这道题是POJ-2253的升级版:https://blog.csdn.net/GYH0730/article/details/77510915
在POJ2253的基础上要加上一个点,显然这个点要加在两点的中点处,提前预处理出任意一点到S,到T的所有路径上最大边的最小值,然后我们可以枚举所有的边,答案为min(max(ds[u], w(u,v)/2, dt[v] ),记录一下最小值就行了
细节上要注意边界的处理
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1050;
const double INF = 1e18;
struct Edge
{
int from,to;
double dist;
Edge(int u,int v,double d):from(u),to(v),dist(d) {}
};
struct HeapNode
{
double d;
int u;
HeapNode(int _u,double _d):u(_u),d(_d){}
bool operator < (const HeapNode& rhs) const
{
return d > rhs.d;
}
};
struct Dijkstra
{
int n,m;
vector<Edge> edges;
vector<int> G[MAXN];
bool vis[MAXN];
double dis[MAXN];
void init(int n)
{
this -> n = n;
for(int i = 0; i <= n + 1; i++) G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,double dist)
{
edges.push_back(Edge(from,to,dist));
m = edges.size();
G[from].push_back(m - 1);
}
void dijkstra(int s)
{
priority_queue<HeapNode> Q;
for(int i = 0; i <= n + 1; i++) {
dis[i] = INF;
vis[i] = false;
}
dis[s] = 0.0;
Q.push(HeapNode(s,0.0));
while(!Q.empty()) {
HeapNode x = Q.top();
Q.pop();
int u = x.u;
if(vis[u]) continue;
vis[u] = true;
for(int i = 0; i < G[u].size(); i++) {
Edge& e = edges[G[u][i]];
if(dis[e.to] > max(dis[u],e.dist)) {
dis[e.to] = max(dis[u],e.dist);
Q.push(HeapNode(e.to,dis[e.to]));
}
}
}
}
}ds,dt;
struct Point
{
double x,y;
}p[MAXN];
inline double cal(int i,int j)
{
return sqrt( (p[i].x - p[j].x) * (p[i].x - p[j].x) +
(p[i].y - p[j].y) * (p[i].y - p[j].y)
);
}
int main(void)
{
freopen("froggy.in","r",stdin);
freopen("froggy.out","w",stdout);
double w,temp;
int n;
scanf("%lf %d",&w,&n);
ds.init(n);dt.init(n);
int S = 0,T = n + 1;
for(int i = 1; i <= n; i++) {
scanf("%lf %lf",&p[i].x,&p[i].y);
}
for(int i = 1; i <= n; i++) {
ds.AddEdge(S,i,p[i].x);
dt.AddEdge(i,S,p[i].x);
ds.AddEdge(i,T,w - p[i].x);
dt.AddEdge(T,i,w - p[i].x);
for(int j = i + 1; j <= n; j++) {
temp = cal(i,j);
ds.AddEdge(i,j,temp);
ds.AddEdge(j,i,temp);
dt.AddEdge(i,j,temp);
dt.AddEdge(j,i,temp);
}
}
ds.dijkstra(S);
dt.dijkstra(T);
double ansx = 0,ansy = 0;
double ans = INF;
int ax,ay;
for(int i = S; i <= T; i++) {
for(int j = S; j <= T; j++) {
if(i == j) continue;
if(i == S && j != T) temp = p[j].x;
else if(i != S && j == T) temp = w - p[i].x;
else if(i == S && j == T) temp = w;
else temp = cal(i,j);
if(ans > max(max(ds.dis[i],temp / 2),max(temp / 2,dt.dis[j]))) {
ax = i;
ay = j;
ans = max(max(ds.dis[i],temp / 2),max(temp / 2,dt.dis[j]));
if(i != S && j != T) {
ansx = (p[i].x + p[j].x) * 0.5;
ansy = (p[i].y + p[j].y) * 0.5;
}
if(i == S && j != T) {
ansx = p[j].x * 0.5;
ansy = p[j].y;
}
if(i != S && j == T) {
ansx = (p[i].x + w) * 0.5;
ansy = p[i].y;
}
if(i == S && j == T) {
ansx = w * 0.5;
ansy = 0;
}
}
}
}
printf("%.12lf %.12lf\n",ansx,ansy);
return 0;
}
/*
10 7
2 2
2 4
5 1
5 3
8 2
7 5
9 4
*/