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. asp.net 用jquery判断fileupload上传文件的大小和类型和名字

    <script language="javascript" type="text/javascript"> //检查上传文件大小和获取文件名 fun ...

  2. swift 自行理解

  3. JS Attribute属性操作

    Attribute是属性的意思,文章仅对部分兼容IE和FF的Attribute相关的介绍. attributes:获取一个属性作为对象 getAttribute:获取某一个属性的值setAttribu ...

  4. CCPC网赛,HDU_5832 A water problem

    Problem Description           Two planets named Haha and Xixi in the universe and they were created ...

  5. Java内存模型JMM与可见性

    Java内存模型JMM与可见性 标签(空格分隔): java 1 何为JMM JMM:通俗地讲,就是描述Java中各种变量(线程共享变量)的访问规则,以及在JVM中将变量存储到内存和从内存中读取变量这 ...

  6. 理解Java中的协变返回类型

    在面向对象程序设计中,协变返回类型指的是子类中的成员函数的返回值类型不必严格等同于父类中被重写的成员函数的返回值类型,而可以是更 "狭窄" 的类型. Java 5.0添加了对协变返 ...

  7. Linq知识大全

    select的源码public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable< ...

  8. 转载的在DOS下操作mysql

    转载原文地址:http://www.server110.com/mysql/201309/1070.html 一.连接MYSQL. 格式: mysql -h主机地址 -u用户名 -p用户密码 1.例1 ...

  9. 有两个数组a,b,大小都为n;通过交换a,b中的元素,使sum(a)-sum(b)最小。

    今天在浏览网页的时候,发现了一个叫做  华为面试题(8分钟写出代码) 的链接,不确定真实性,纯属好奇,就点进去看看 这个可能是很老的题目吧,因为我看到这题目时,底下有好多评论了.提到XX排序,内存占用 ...

  10. linq any()方法实现sql in()方法的效果

    public IQueryable<Vsec009ComSecComp> QueryList(Sec009ComSecCompQueryCondition condition) { var ...