Have you ever played DOTA? If so, you may know the hero, Invoker. As one of the few intelligence carries, Invoker has 10 powerful abilities. One of them is the Ice Wall: Invoker generates a wall of solid ice directly in front of him, and the bitter cold emanating from it greatly slows nearby enemies and deals damage each second.

Now consider the map as a plane. You are now at point s, and want to move to point t. But Invoker has placed N ice walls on the map. Your moving speed is 1 per second, but you need k seconds to pass an ice wall. Time is precious, you must get to point t as quickly as possible. What's the minimum time you need?

For convenience, you can assume that all ice walls are segments (no width) either parallel to X-axis or to Y-axis. Segments are strictly disjoint (have no common point). Point s and t are not on any segment (have no common point).

You will not be slowed when pass the end point of a segment or walk along a segment.

 

Input

The input begins with an integer T, indicating the number of test cases. For each case, the first line is two integers N and k (1 <= N <= 500, 0 <= k <= 10^8), indicating the number of segments and the time needed to pass an ice wall. Next N lines, each have four integers x1, y1, x2, y2, indicating two end points of a segment, (x1, y1) and (x2, y2). Next line has two integers xs and ys, representing the coordinates of starting point s. The last line also has two integers xt and yt, representing the coordinates of target point t. For every point, |x| and |y| <= 108.

 

Output

For each case, output one line containing the minimum time in second needed to get to t from s. The answer should be given within an absolute or relative error of 10−6.

 

Sample Input

3
1 1
1 0 1 2
0 0
2 0
1 1
1 -2 1 2
0 0
2 0
1 3
1 -2 1 2
0 0
2 0

Sample Output

2.000000
3.000000
4.472136
  
  这道题还是有些挑战的,可以一眼看出是最短路,但如何处理出点对的直接路径?
  考虑极角排序,我不会,就用三角函数的sin和cos代替,然后用bit维护,可以做到N²logN。
 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps=1e-;
const int N=,M=; struct Node{int x,y,tp;}point[N],s,t,tmp;
struct Data{Node t;int id;double k,d;}st[N];
int hsh[*N],bit[*N],csh,top;double G[N][N]; double Dis(Node a,Node b){
return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
} double K1(Node b){return 1.0*(b.x-tmp.x)/Dis(tmp,b);}
double K2(Node b){return 1.0*(b.y-tmp.y)/Dis(tmp,b);} int Rk1(int tp){return tp==?:tp==?:;}
int Rk2(int tp){return tp==?:tp==?:;} bool cmp1(Data p,Data q){
Node a=p.t,b=q.t;
if(fabs(p.k-q.k)>)return q.k-p.k>=eps;
if(a.tp==&&b.tp==)return q.d-p.d>=eps;
if(a.tp==&&b.tp==)return p.d-q.d>=eps;
return Rk1(a.tp)<Rk1(b.tp);
} bool cmp2(Data p,Data q){
Node a=p.t,b=q.t;
if(fabs(p.k-q.k)>)return p.k<q.k;
if(a.tp==&&b.tp==)return p.d<q.d;
if(a.tp==&&b.tp==)return p.d>q.d;
return Rk2(a.tp)<Rk2(b.tp);
}
int Query(int x,int y){int ret=;
x=lower_bound(hsh+,hsh+csh+,x)-hsh-;
while(x){ret-=bit[x];x-=x&(-x);}
y=lower_bound(hsh+,hsh+csh+,y)-hsh;
while(y){ret+=bit[y];y-=y&(-y);}
return ret;
} void Add(int x,int d){
x=lower_bound(hsh+,hsh+csh+,x)-hsh;
while(x<=csh)bit[x]+=d,x+=x&(-x);
} int tot,n,ice,T;
void Solve1(int p){
tmp=point[p];top=;
for(int i=;i<=tot;i++){
Node b=point[i];if(tmp.y<=b.y)continue;
st[++top]=(Data){b,i,K1(b),Dis(tmp,b)};
}sort(st+,st+top+,cmp1);
memset(bit,,sizeof(bit));
for(int i=;i<=top;i++){
Data b=st[i];Node c=b.t;
if(c.tp==)Add(c.y,-);
G[b.id][p]+=ice*Query(c.y,tmp.y);
G[p][b.id]+=ice*Query(c.y,tmp.y);
if(c.tp==)Add(c.y,);
}
} void Solve2(int p){
tmp=point[p];top=;
for(int i=;i<=tot;i++){
Node b=point[i];if(tmp.x<=b.x)continue;
st[++top]=(Data){b,i,K2(b),Dis(tmp,b)};
}sort(st+,st+top+,cmp2);
memset(bit,,sizeof(bit));
for(int i=;i<=top;i++){
Data b=st[i];Node c=b.t;
if(c.tp==)Add(c.x,-);
G[b.id][p]+=ice*Query(c.x,tmp.x);
G[p][b.id]+=ice*Query(c.x,tmp.x);
if(c.tp==)Add(c.x,);
}
} int vis[N];double dis[N];
double Dij(int s,int t){
for(int i=;i<N;i++)
dis[i]=1e20,vis[i]=;dis[s]=;
for(int i=,p;i<=tot;i++){p=;
for(int j=;j<=tot;j++)
if(!vis[j]&&dis[p]>dis[j])p=j;
vis[p]=true;
for(int j=;j<=tot;j++)
dis[j]=min(dis[j],dis[p]+G[p][j]);
}
return dis[t];
} void Initial(){
memset(G,,sizeof(G));
tot=csh=;
} int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&ice);Initial();
for(int i=,x1,y1,x2,y2;i<=n;i++){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
hsh[++csh]=x1;hsh[++csh]=x2;
hsh[++csh]=y1;hsh[++csh]=y2;
if(x1==x2&&y1==y2)continue;
if(x1==x2){
if(y1>y2)swap(y1,y2);
point[++tot]=(Node){x1,y1,};
point[++tot]=(Node){x2,y2,};
}
if(y1==y2){
if(x1>x2)swap(x1,x2);
point[++tot]=(Node){x1,y1,};
point[++tot]=(Node){x2,y2,};
}
} scanf("%d%d",&s.x,&s.y);
scanf("%d%d",&t.x,&t.y); hsh[++csh]=s.x;hsh[++csh]=s.y;
hsh[++csh]=t.x;hsh[++csh]=t.y; sort(hsh+,hsh+csh+);
csh=unique(hsh+,hsh+csh+)-hsh-; point[++tot]=(Node){s.x,s.y,};
point[++tot]=(Node){t.x,t.y,}; for(int i=;i<=tot;i++)Solve1(i);
for(int i=;i<=tot;i++)Solve2(i); for(int i=;i<=tot;i++)
for(int j=;j<=tot;j++)
G[i][j]+=Dis(point[i],point[j]);
printf("%.6lf\n",Dij(tot-,tot));
}
return ;
}

  WA在求dis的平方上了,注意会爆int。

附上数据生成器:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
using namespace std;
int G[][],h[];
int main(){
srand(time(NULL));
int T=,n=,w=;
printf("%d\n",T);
while(T--){
printf("%d %d\n",n,rand()%w);
int x,y,a,b,l;
for(int i=;i<w;i++){
h[i]=rand()*rand()%;
if(rand()%)h[i]*=-;
}
sort(h,h+w);
memset(G,,sizeof(G));
for(int i=;i<=n;i++){
while(true){
x=rand()%w;y=rand()%w;
while(G[x][y])x=rand()%w,y=rand()%w;
if(rand()%){
a=x;l=;
while(y+l+<=w&&G[x][y+l]==)l++;
if(l==)continue;b=y+rand()%(l-)+;
}
else{
b=y;l=;
while(x+l+<=w&&G[x+l][y]==)l++;
if(l==)continue;a=x+rand()%(l-)+;
}
for(int j=x;j<=a;j++)
for(int k=y;k<=b;k++)
G[j][k]=;
printf("%d %d %d %d\n",h[x],h[y],h[a],h[b]);
break;
}
}
x=rand()%w;y=rand()%w;
while(G[x][y])x=rand()%w,y=rand()%w;
printf("%d %d\n",h[x],h[y]);G[x][y]=;
x=rand()%w;y=rand()%w;
while(G[x][y])x=rand()%w,y=rand()%w;
printf("%d %d\n",h[x],h[y]);
}
return ;
}

最短路(数据处理):HDU 5817 Ice Walls的更多相关文章

  1. HDU 6187 Destroy Walls (思维,最大生成树)

    HDU 6187 Destroy Walls (思维,最大生成树) Destroy Walls *Time Limit: 8000/4000 MS (Java/Others) Memory Limit ...

  2. 单源最短路模板 + hdu - 2544

    Floyd Floyd 本质上类似一种动态规划,dp [ i ] [ j ] = dp [ i ] [ k ] + dp[ k ] [ j ]. /** * Night gathers, and no ...

  3. HDU 6187 Destroy Walls

    Destroy Walls Long times ago, there are beautiful historic walls in the city. These walls divide the ...

  4. HDU 6187 Destroy Walls (对偶图最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6187 题意:有一个V个结点M条边的带边权无向平面图,有一个人在一个区域,要拆一些墙使得他可以到达任意一 ...

  5. 【最短路】HDU 1688 Sightseeing

    题目大意 给出一个有向图(可能存在重边),求从\(S\)到\(F\)最短路的条数,如果次短路的长度仅比最短路的长度多1,那么再加上次短路的条数. 输入格式 第一行是数据组数\(T\). 对于魅族数据, ...

  6. 【转】最短路&差分约束题集

    转自:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548 A strange lift基础最短路(或bfs)★254 ...

  7. 转载 - 最短路&差分约束题集

    出处:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548    A strange lift基础最短路(或bfs)★ ...

  8. HDU2544 最短路dij

    纯最短路. ///HDU 2544堆优化的最短路 #include <cstdio> #include <iostream> #include <sstream> ...

  9. ACM-最短路(SPFA,Dijkstra,Floyd)之最短路——hdu2544

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

随机推荐

  1. iOS imagePicker使用方法,方便使用!三步轻松搞定!

    自己总结的修改头像的方法,只为方便自己查询使用!转发 步骤:1.遵守代理协议 <UIImagePickerControllerDelegate,UINavigationControllerDel ...

  2. HDU 4089 Activation(概率DP)(转)

    11年北京现场赛的题目.概率DP. 公式化简起来比较困难....而且就算结果做出来了,没有考虑特殊情况照样会WA到死的.... 去参加区域赛一定要考虑到各种情况.   像概率dp,公式推出来就很容易写 ...

  3. GIS科研站

    http://www.3sbase.com/3sbase/ 近年来,地理信息科学发展迅猛,科研人员日益增多,但目前尚缺乏良好的交流平台,致使优秀的科研成果难以推广.同时,对于大量的GIS学生而言,对国 ...

  4. (poj)1679 The Unique MST 求最小生成树是否唯一 (求次小生成树与最小生成树是否一样)

    Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definit ...

  5. (转)IOS学习笔记-2015-03-29 int、long、long long取值范围

    unsigned - - unsigned - - unsigned __int64的最大值: __int64的最小值:- unsigned __int64的最大值:  

  6. Headfirst设计模式的C++实现——工厂方法(Factory Method)

    引用原书的一句话:所有的工厂模式都用来封装对象的创建,工厂方法模式通过让子类决定该创建的对象是什么来达到封装的目的. Pizza类及其派生类与上一例相同 PizzaStore.h #ifndef _P ...

  7. 锋利的Jquery解惑系列(三)------ 各路选择器大聚会

    申明:初次学习Jquery的选择器时只记得几个和css选择器类似的几个,在这里列出书上写上的各路选择器方便以后的查询和现在的学习 所有例子都来自书上 测试画面: 一.基本选择器 #id, $(&quo ...

  8. nodejs中间层现实

    初次接触nodejs,是一种非常神奇的东西,未来必火起来.个人觉得最大优势npm命令. 闲话少说,直入主题.这是一个博客项目,php最为服务端,提供数据给node:nodejs+express作为中间 ...

  9. nginx重新加载配置

    1.kill -HUP `cat /usr/local/nginx/logs/nginx.pid` 2./usr/local/nginx/sbin/nginx -s reload

  10. MVVM Light 一个窗口承载两个视图

    MVVM Light 一个窗口承载两个视图   原文地址:http://www.codeproject.com/Articles/323187/MVVMLight-Using-Two-Views 本文 ...