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 }