P1783 海滩防御 最短路

题意:题目的意思就是要建立一道防线,从x=0,链接到x=n;

   题目会给出m个哨点,每个哨点可以包含半径为k的范围,通过这些哨点来建立防线

   

 

   如图,建立类似这样的一条防线,那么我们就是要从左边建到右边,找一条最短路

思路:假如我们单独处理题目中给出的哨点的话,那么两岸还没处理到,所以我们增加m+1(设立在左岸),m+2两个点(设立在右岸)

   然后就开始建边,最后走最大值最短路即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+10;
 4 double dis[maxn]; int vis[maxn];
 5 double x[maxn],y[maxn];
 6 int n,m;
 7 struct node
 8 {
 9     int v,nxt;
10     double w;
11 }G[1000010]; int head[1000010]; int num=0;
12 double mx(double t1,double t2)
13 {
14     if(t1>t2) return t1;
15     else return t2;
16 }
17 void add(int u,int v,double w)
18 {
19     G[++num].v=v;G[num].w=w;G[num].nxt=head[u];head[u]=num;
20 }
21 double cal(int t1,int t2)
22 {
23     return sqrt((x[t1]-x[t2])*(x[t1]-x[t2])+(y[t1]-y[t2])*(y[t1]-y[t2]));
24 }
25 void SPFA()
26 {
27     memset(vis,0,sizeof(vis));
28     for(int i=1;i<=m+2;i++){
29         dis[i]=1000000000.0;
30     }
31     queue<int>q;
32     q.push(m+1);
33     vis[1+m]=1;
34     dis[1+m]=0;
35     while(!q.empty()){
36         int u=q.front();
37         q.pop();
38         vis[u]=0;
39         for(int i=head[u];i;i=G[i].nxt){
40             int v=G[i].v;
41             double w=G[i].w;
42             if(dis[v]>mx(dis[u],w)){
43                 dis[v]=mx(dis[u],w);
44                 if(!vis[v]){
45                     q.push(v);
46                     vis[v]=1;
47                 }
48             }
49         }
50     }
51 }
52 int main()
53 {
54     scanf("%d%d",&n,&m);
55     for(int i=1;i<=m;i++){
56         scanf("%lf%lf",&x[i],&y[i]);
57         add(m+1,i,x[i]);add(i,m+1,x[i]);
58         double tmp=double(n)-x[i];
59         add(m+2,i,tmp);add(i,m+2,tmp);
60     }
61     for(int i=1;i<=m;i++){
62         for(int j=i+1;j<=m;j++){
63             double tmp=cal(i,j)/2;
64             add(i,j,tmp);
65             add(j,i,tmp);
66         }
67     }
68     SPFA();
69     printf("%.2f\n",dis[m+2]);
70 }
View Code

 

posted @ 2020-04-16 15:40  古比  阅读(113)  评论(0编辑  收藏  举报