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. 04_天气查询_JAX-WS方式_服务端

    [简述] WebService的Java实现共有三种方式:JAX-WS(JAX-RPC).JAXM&SAAJ.JAX-RS. JAX-WS: JAX-WS  的全称为 Java API for ...

  2. 05_Excel操作_01_简单导入导出

    [Excel组成] 主要由四部分组成: 1.工作簿 每一个Excel文件都可以看成是一个工作簿,当打开一个Excel文件时,相当于打开了一个Excel工作簿. 2.工作表 当打开了Excel工作簿后, ...

  3. GitHub Windows客户端部署

    下载网址:https://windows.github.com 点击下载按钮即可下载一个小程序,这个小程序会去服务器端下载完整的Windows版客户端,然后自动安装. 如果安装出错的话,那就打开IE浏 ...

  4. MFC设置对话框透明背景

    在对话框初始化函数OnInitDialog函数中添加如下代码: SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(GetSafeHwnd(), ...

  5. Sdut 2164 Binomial Coeffcients (组合数学) (山东省ACM第二届省赛 D 题)

    Binomial Coeffcients TimeLimit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 输入 输出 示例输入 1 1 10 2 9 ...

  6. 结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别

    之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略.这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个 ...

  7. docker 挂在本地目录

    docker run -i -t -v /home/:/opt/data jenkins /bin/bash    运行jenkins,把本地中的/home/   挂载到虚拟机中的/opt/data/ ...

  8. linux下多线程踩过的坑(不定更新)

    1,多线程下整个进程的退出 <<APUE>>关于进程环境一章中指出了进程退出的8个条件: ... (4)最后一个线程从启动例程中返回 (5)最后一个线程调用pthread_ex ...

  9. 【转】关于oracle with as用法

    原文链接:关于oracle with as用法 with as语法–针对一个别名with tmp as (select * from tb_name) –针对多个别名with   tmp as (se ...

  10. C的快速趋向实验 -->

    今天刚学到C的一个新玩法,非常有意思,叫趋向于,写作“-->”,比如说如果要实现一个倒数的程序,我们可以定义一个变量 counter,然后让它趋向于0... #include <stdio ...