生活随笔
收集整理的這篇文章主要介紹了
starway(NOIP模拟测试24)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目大意:平面上有一個$N \times M$的矩形,矩形內有K個點,現給出每個點的坐標,找一條從左邊界到右邊界的路徑,使路徑到矩形上下邊界及矩形內點的最小距離最大。
20%:$(K<=10)$
直接暴搜。
50%:$(K<=400)$
我們以點為圓心畫圓。
那么存在一條路徑的條件是這些圓沒有將半徑封死。
我們可以二分圓的半徑,每次將相交的圓合并,將上下邊界視作點,查詢上下邊界是否在同一集合內部,若在,則判定失敗。
時間復雜度$O(K^2*log_2ANS)$
100%:$(K<=6000)$
我們發現二分答案占有相當復雜度,于是我們考慮去掉。
我們把所有點連同上下邊界連在一張圖里,發現起到限制作用的只用上下邊界之間的通路。
答案即為最大值最小的通路上邊權的最大值。
做一遍最小生成樹,DFS求出上下邊界之間的通路上的最大邊權。
由于是完全圖,我們只能用Prim,并且為了減少內存,邊權要現算。
時間復雜度$O(K^2)$
Code:
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cmath>
5 #include<vector>
6 using namespace std;
7 const int N=
6003;
8 int n,m,k,U,D;
9 int fi[N],f[N];
10 long long a[N],b[N];
11 double d[N];
12 bool v[N];
13 vector<
int>
e[N];
14 vector<
double>
l[N];
15 void add(
int x,
int y,
double z)
16 {
17 e[x].push_back(y);
18 l[x].push_back(z);
19 }
20 double get(
int x,
int y)
21 {
22 if((x==D&&y==U)||(x==U&&y==D))
return m;
23 if(x==D)
return b[y];
24 if(y==D)
return b[x];
25 if(x==U)
return m-
b[y];
26 if(y==U)
return m-
b[x];
27 double ans=(a[x]-a[y])*(a[x]-a[y])+(b[x]-b[y])*(b[x]-
b[y]);
28 return sqrt(ans);
29 }
30 void dfs(
int x,
int p)
31 {
32 for(
int i=
0;i<e[x].size();i++
){
33 int y=
e[x][i];
34 if(y==p)
continue;
35 d[y]=
max(d[x],l[x][i]);
36 dfs(y,x);
37 }
38 }
39 void Prim()
40 {
41 for(
int i=
1;i<=k+
2;i++
)
42 d[i]=
99999999;
43 d[
1]=
0;
44 for(
int i=
1;i<=k+
1;i++
){
45 int x=
0;
46 for(
int j=
1;j<=k+
2;j++
){
47 if(!v[j]&&(x==
0||d[j]<d[x])) x=
j;
48 }
49 v[x]=
true;
50 for(
int j=
1;j<=k+
2;j++
){
51 double y=
get(x,j);
52 if(!v[j]&&y<
d[j]){
53 d[j]=y;f[j]=
x;
54 }
55 }
56 }
57 }
58 int main()
59 {
60 scanf(
"%d%d%d",&n,&m,&
k);
61 U=k+
1;D=k+
2;
62 for(
int i=
1;i<=k;i++
)
63 scanf(
"%lld%lld",&a[i],&
b[i]);
64 Prim();
65 for(
int i=
2;i<=k+
2;i++
){
66 add(i,f[i],d[i]);add(f[i],i,d[i]);
67 d[i]=
0;
68 }
69 dfs(U,
0);
70 printf(
"%.8lf\n",d[D]/
2.0);
71 return 0;
72 }
view code
轉載于:https://www.cnblogs.com/hz-Rockstar/p/11370517.html
總結
以上是生活随笔為你收集整理的starway(NOIP模拟测试24)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。