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. 记一次ftp服务器错误 centOS 6.4 vsftpd 500 illegal port command

    这个错误是因为是主动模式的,应该改为被动模式 以下是操作过程: iptables中加 -A INPUT -p tcp -m state --state NEW -m tcp --dport 10221 ...

  2. 关于C++几个容易混淆的概念总结

    1.函数指针和指针函数 函数指针说的就是一个指针,但这个指针指向的函数,不是普通的基本数据类型或者类对象.函数指针的定义: int (*func)(int a, int b); // 声明函数指针 指 ...

  3. Android MVP模式

    转自http://segmentfault.com/blogs,转载请注明出处Android MVP Pattern Android MVP模式\[1\]也不是什么新鲜的东西了,我在自己的项目里也普遍 ...

  4. ASP.NET服务端基本控件介绍

    ASP.NET服务端基本控件介绍 大概分为三种控件: HTML控件,ASP.NET把HTML控件当成普通字符串渲染到浏览器端,不去检查正确性,无法在服务端进行处理ASP.NET服务端控件,经过ASP. ...

  5. tmux复制到windows剪贴板/粘贴板的坑

    以下所有操作都是在windows下面用putty连接linux centos6的情景下. 一直很纳闷为什么在tmux模式下不能把复制到的文字放到系统的粘贴板里面呢?通过层层阻碍,终于找到了原因. 去掉 ...

  6. 网站开发常用jQuery插件总结(14)图片修剪插件Jcrop

    一.插件功能 用于对图片进行修剪.但是在使用Jcrop时,还需要配合服务器端开发语言(如asp.net,php等)使用. 二.官方地址 http://deepliquid.com/content/Jc ...

  7. c#面向对象小结

    特点: 1:将复杂的事情简单化. 2:面向对象将以前的过程中的执行者,变成了指挥者. 3:面向对象这种思想是符合现在人们思考习惯的一种思想. 过程和对象在我们的程序中是如何体现的呢?过程其实就是函数: ...

  8. linux环境下安装php扩展

    本文只提供源码安装的方法(已安装pcntl为例) 其他方法请参考:http://doc3.workerman.net/appendices/install-extension.html 1.利用php ...

  9. JavaScript学习总结【11】、JS 运动

    动画效果在网站中是一种非常常见的交互式体验效果,比如侧边栏分享.图片淡入淡出,我们把这种动画效果就叫做运动,也就是让物体动起来.如果想让一个物体动起来,无非就是改变它的速度,也就是改变属性值,比如 l ...

  10. [转]maven插件的开发

    原文链接: http://clojure.iteye.com/blog/1124188 另一篇文章 http://blog.csdn.net/csfreebird/article/details/77 ...