题解
2026-07-16 09:25:24
发布于:山西
12阅读
0回复
0点赞
依旧代码:
#include <bits/stdc++.h>
#define N 100005
#define x first
#define y second
using namespace std;
typedef pair<double,double> point;
const double eps=1e-8;
const double pi=acos(-1);
int e[N],ne[N],h[N],w[N],idx;
int vis[1005],dis[1005];
int ed[1005];
typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
void add(int u,int v,int dist) {
e[idx]=v,ne[idx]=h[u],w[idx]=dist,h[u]=idx++;
}
point p[N];
int cnt;
int q[N],hh,tt;
struct line {
point x,y;
int id;
} l[N];
int sign(double x) {
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
int fcmp(double x,double y) {
if(fabs(x-y)<eps) return 0;
return x<y?-1:1;
}
point operator+(const point& a,const point& b) {
return {a.x+b.x,a.y+b.y};
}
point operator-(const point& a,const point& b) {
return {a.x-b.x,a.y-b.y};
}
point operator*(const point& a,double b) {
return {a.x*b,a.y*b};
}
point operator/(const point& a,double b) {
return {a.x/b,a.y/b};
}
double dot(const point& a,const point& b) {
return a.x*b.x+a.y*b.y;
}
double cross(const point& a,const point& b) {
return a.x*b.y-a.y*b.x;
}
double area(const point& a,const point& b,const point& c) {
return cross(b-a,c-a);
}
double len(const point& a) {
return sqrt(dot(a,a));
}
double get_dist(const point& a,const point& b) {
return len(a-b);
}
double get_angle(const line& a) {
point o=a.y-a.x;
return atan2(o.y,o.x);
}
bool cmp(const line& a,const line& b) {
double angle1=get_angle(a),angle2=get_angle(b);
if(!fcmp(angle1,angle2)) return area(a.x,a.y,b.y)>0;
return angle1<angle2;
}
point rotate(const point& a,double b) {
return {a.x*cos(b)+a.y*sin(b),-a.x*sin(b)+a.y*cos(b)};
}
point get_line_intersection(const point& p,const point& q,const point& v,const point& w) {
point u=p-q;
double t=cross(w,u)/cross(v,w);
return p+v*t;
}
point get_line_intersection(const line& a,const line& b) {
return get_line_intersection(a.x,b.x,a.y-a.x,b.y-b.x);
}
bool on_right(const line& a,const line& b,const line& c) {
point o=get_line_intersection(b,c);
return sign(area(a.x,a.y,o))<0;
}
void half_plane_intersection(int id) {
hh=0,tt=-1;
sort(l,l+cnt,cmp);
for(int i=0; i<cnt; i++) {
if(i&&!fcmp(get_angle(l[i]),get_angle(l[i-1]))) continue;
while(hh+1<=tt&&!on_right(l[i],l[q[tt-1]],l[q[tt]])) tt--;
while(hh+1<=tt&&!on_right(l[i],l[q[hh]],l[q[hh+1]])) hh++;
q[++tt]=i;
}
while(hh+1<=tt&&!on_right(l[q[hh]],l[q[tt-1]],l[q[tt]])) tt--;
while(hh+1<=tt&&!on_right(l[q[tt]],l[q[hh]],l[q[hh+1]])) hh++;
for(int i=hh; i<=tt; i++) {
int tmp=l[q[i]].id;
if(tmp==-1) ed[id]=1;
else add(id,tmp,1);
}
}
line getmidline(const point& a,const point& b,int id) {
point u=(a+b)/2;
point v=b-a;
return {u,u+rotate(v,pi/2),id};
}
void dij(int st) {
priority_queue<pii,vector<pii>,greater<pii>> qq;
memset(dis,0x3f,sizeof dis);
dis[st]=1;
qq.push({1,st});
while(!qq.empty()) {
auto p=qq.top();
qq.pop();
int u=p.y;
if(vis[u]) continue;
vis[u]=1;
for(int i=h[u]; ~i; i=ne[i]) {
int v=e[i];
if(dis[u]+w[i]<dis[v]) {
dis[v]=dis[u]+w[i];
if(!vis[v]) qq.push({dis[v],v});
}
}
}
}
int main() {
int t;
cin >> t;
while(t--) {
memset(h,-1,sizeof h);
memset(ed,0,sizeof ed);
memset(vis,0,sizeof vis);
idx=0;
int n;
cin >> n;
int a,b,c,d;
double mindist=1e18;
cin >> a >> b >> c >> d;
point o= {c,d};
int st;
if(n==0) {
cout << 0 << endl;
continue;
}
int tot=0;
for(int i=0; i<n; i++) {
int xx,yy;
cin >> xx >> yy;
if(xx>a||yy>b||xx<0||yy<0) continue;
p[tot]= {xx,yy};
if(mindist>get_dist(p[tot],o)) {
st=tot;
mindist=get_dist(p[tot],o);
}
tot++;
}
for(int i=0; i<tot; i++) {
cnt=0;
for(int j=0; j<tot; j++) {
if(j==i) continue;
l[cnt++]=getmidline(p[i],p[j],j);
}
l[cnt++]= {{0,0},{0,b},-1};
l[cnt++]= {{a,0},{0,0},-1};
l[cnt++]= {{0,b},{a,b},-1};
l[cnt++]= {{a,b},{a,0},-1};
half_plane_intersection(i);
}
dij(st);
int ans=0x3f3f3f3f;
for(int i=0; i<tot; i++) if(ed[i]) ans=min(ans,dis[i]);
cout << ans << endl;
}
return 0;
}
写吧!
全部评论 1
6
2026-07-20 来自 山西
0














有帮助,赞一个