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. swift入门-day01-基本语法

    主要内容: 1.常量和变量 2.Optional 3.控制流 4.循环 5.字符串 6.集合 变量和常量 定义 let 定义常量,一经赋值不允许再修改 var 定义变量,赋值之后仍然可以修改 自动推导 ...

  2. imageWithContentsOfFile读取全路径返回的image为空的解决方法

    下载图片缓存到本地沙盒里,发现用 imageWithContentsOfFile去读取的时候,40%左右的几率会读取为空. 查找资料和文档后找到解决方法 路径:当这次的时候是/var/mobile/C ...

  3. HDU 4627 The Unsolvable Problem(简单题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4627 题目大意:给定一个整数n(2 <= n <= 109),满足a+b=n并且[a,b] ...

  4. ASP.NET中的验证控件

    ASP.NET提供了如下的控件: RequiredFieldValidator: 字段必填 (ControlTovalidate设定要验证的控件) RangeValidator: 值在给定的最大值,最 ...

  5. think ajax 应用

    首先得引入 jquery 文件,另外定义一个处理的 js.js 文件 如实现用 post 传输方法: 模板文件: <script type="text/javascript" ...

  6. php操作memcache的用法、详解和方法介绍

    1.简介 memcache模块是一个高效的守护进程,提供用于内存缓存的过程式程序和面向对象的方便的接口,特别是对于设计动态web程序时减少对数据库的访问. memcache也提供用于通信对话(sess ...

  7. Groovy 数组操作

    将字符串转为map def str="['汤菜':['1000000028','1000000030'],'肉菜':['1000000032'],'素材':['1000000031']]&q ...

  8. C# 判断中文字符(字符串)

    在unicode 字符串中,中文的范围是在4E00..9FFF:CJK Unified Ideographs.通过对字符的unicode编码进行判断来确定字符是否为中文.protected bool  ...

  9. (转载)MVC + JQUERY + AJAX的几种方式

    MVC + JQUERY + AJAX的几种方式 // 传过去一个简单值,获取一个简单值 $.ajax({            type: "GET",         url: ...

  10. C语言实现的单链表

    链表是一种线性表,但是并不是顺序存储,而是每个节点里面存储着下一个节点的指针,把存储数据元素的数据串链起来. 单链表的基本实现: typedef int DataType;//定义单链表typedef ...