按题意把图建出来跑最短路就行了。注意遮挡不会影响答案,所以不必考虑,因为走直线经过遮挡的时候,一定不会比答案更优。

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstring>
using namespace std;
#define EPS 0.00000001
#define N 109
int T,n,H,X;
int hs[N],xs[N],ds[N];
bool is[N];
double sqr(int x)
{
return (double)x*(double)x;
}
int e,v[N*N*4],first[N],next[N*N*4];
double w[N*N*4];
void AddEdge(int U,int V,double W)
{
v[++e]=V;
w[e]=W;
next[e]=first[U];
first[U]=e;
}
double d[N];
bool vis[N];
struct Point{double d;int u;
Point(const double &X,const int &Y){d=X;u=Y;}
Point(){}};
bool operator < (Point a,Point b){return a.d>b.d;}
priority_queue<Point>q;
void dijkstra(int S)
{
for(int i=1;i<=n+2;++i) d[i]=1000000007.0;
d[S]=0; q.push(Point(0.0,S));
while(!q.empty())
{
Point x=q.top(); q.pop();
if(!vis[x.u])
{
vis[x.u]=1;
for(int i=first[x.u];i;i=next[i])
if(d[v[i]]-d[x.u]-w[i]>EPS)
{
d[v[i]]=d[x.u]+w[i];
q.push(Point(d[v[i]],v[i]));
}
}
}
}
int main()
{
freopen("street.in","r",stdin);
scanf("%d",&T);
for(;T;--T)
{
memset(v,0,sizeof(v));
memset(first,0,sizeof(first));
memset(w,0,sizeof(w));
memset(next,0,sizeof(next));
memset(vis,0,sizeof(vis));
e=0;
scanf("%d%d%d",&n,&H,&X);
for(int i=1;i<=n;++i)
scanf("%d%d%d%d",&hs[i],&xs[i],&ds[i],&is[i]);
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j)
if(is[i]==is[j] || (is[i]!=is[j] && xs[i]+xs[j]>X))
{
AddEdge(i,j,ds[j]-(ds[i]+hs[i])>=0 ? ds[j]-(ds[i]+hs[i]) : ds[i]-(ds[j]+hs[j]));
AddEdge(j,i,ds[j]-(ds[i]+hs[i])>=0 ? ds[j]-(ds[i]+hs[i]) : ds[i]-(ds[j]+hs[j]));
}
else if((ds[i]+hs[i]>=ds[j] && ds[i]<=ds[j]+hs[j]) ||
(ds[j]+hs[j]>=ds[i] && ds[j]<=ds[i]+hs[i]))
{
AddEdge(i,j,X-(xs[i]+xs[j]));
AddEdge(j,i,X-(xs[i]+xs[j]));
}
else if(ds[i]+hs[i]<ds[j])
{
AddEdge(i,j,sqrt(sqr(ds[j]-(ds[i]+hs[i]))+sqr(X-(xs[i]+xs[j]))));
AddEdge(j,i,sqrt(sqr(ds[j]-(ds[i]+hs[i]))+sqr(X-(xs[i]+xs[j]))));
}
else
{
AddEdge(i,j,sqrt(sqr(ds[i]-(ds[j]+hs[j]))+sqr(X-(xs[i]+xs[j]))));
AddEdge(j,i,sqrt(sqr(ds[i]-(ds[j]+hs[j]))+sqr(X-(xs[i]+xs[j]))));
}
for(int i=1;i<=n;++i)
{
AddEdge(n+1,i,ds[i]);
AddEdge(i,n+1,ds[i]);
AddEdge(i,n+2,H-(ds[i]+hs[i]));
AddEdge(n+2,i,H-(ds[i]+hs[i]));
}
dijkstra(n+1);
printf("%.6lf\n",d[n+2]);
}
return 0;
}

【最短路】【Heap-dijkstra】Gym - 101147B - Street的更多相关文章

  1. [POJ3463] Sightseeing(次短路 Heap + Dijkstra)

    传送门 用dijkstra比较好,spfa可能有的重复 dis[x][2]:dis[x][0]表示起点到x的最短路.dis[x][1]表示起点到x的次短路: tot[x][2]:tot[x][0]表示 ...

  2. 最短路计数——Dijkstra

    题目: 给出一个N个顶点M条边的无向无权图,顶点编号为1−N.问从顶点1开始,到其他每个点的最短路有几条. ——传送门 受到题解的启发,用 Dijkstra A掉(手工代码) 思路: 1.无向无权图, ...

  3. BZOJ 3040: 最短路(road) [Dijkstra + pb_ds]

    3040: 最短路(road) Time Limit: 60 Sec  Memory Limit: 200 MBSubmit: 2476  Solved: 814[Submit][Status][Di ...

  4. Radix Heap ---Dijkstra算法的优化 BY Gremount

    Radix Heap 算法是在Dijkstra的Dial实现的基础上,通过减少对桶的使用,来优化算法的时间复杂度: Dial 时间复杂度是O(m+nC)     -------C是最长的链路 Radi ...

  5. 10行实现最短路算法——Dijkstra

    今天是算法数据结构专题的第34篇文章,我们来继续聊聊最短路算法. 在上一篇文章当中我们讲解了bellman-ford算法和spfa算法,其中spfa算法是我个人比较常用的算法,比赛当中几乎没有用过其他 ...

  6. UVA 11374 Airport Express 机场快线(单源最短路,dijkstra,变形)

    题意: 给一幅图,要从s点要到e点,图中有两种无向边分别在两个集合中,第一个集合是可以无限次使用的,第二个集合中的边只能挑1条.问如何使距离最短?输出路径,用了第二个集合中的哪条边,最短距离. 思路: ...

  7. poj 2449 Remmarguts' Date(第K短路问题 Dijkstra+A*)

    http://poj.org/problem?id=2449 Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Subm ...

  8. hdoj 2544 最短路【dijkstra or spfa】

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  9. 最短路和次短路问题,dijkstra算法

    /*  *题目大意:  *在一个有向图中,求从s到t两个点之间的最短路和比最短路长1的次短路的条数之和;  *  *算法思想:  *用A*求第K短路,目测会超时,直接在dijkstra算法上求次短路; ...

随机推荐

  1. 小K的农场

    小K的农场 题目描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述: 农场a比农场b至少多种植了 ...

  2. PAT团体程序设计大赛---(模拟)

    L1-1 古风排版(20 分) 中国的古人写文字,是从右向左竖向排版的.本题就请你编写程序,把一段文字按古风排版. 输入格式: 输入在第一行给出一个正整数N(<100),是每一列的字符数.第二行 ...

  3. 【Foreign】染色 [LCT][线段树]

    染色 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output Sample Input 13 0 1 0 2 1 11 1 ...

  4. Hackerrank [World CodeSprint 11] City Construction

    传送门:https://www.hackerrank.com/contests/world-codesprint-11/challenges/hackerland [题解] 因为加点每次加1个点1条边 ...

  5. 12.22笔记(关于CALayer//Attributes//CALayer绘制图层//CALayer代理绘图//CALayer动画属性//CALayer自定义子图层//绘图pdf文件//绘图渐变效果)

    12.22笔记 pdf下载文件:https://www.evernote.com/shard/s227/sh/f81ba498-41aa-443b-81c1-9b569fcc34c5/f033b89a ...

  6. [bzoj3884]上帝与集合的正确用法——欧拉函数

    题目大意 题解 出题人博客 代码 #include <bits/stdc++.h> using namespace std; const int M = 10001000; int phi ...

  7. hdu 1518 Square(深搜+剪枝)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! ...

  8. 数据安全之MD5、SHA-1、CRC32区别

    crc32 — 计算一个字符串的 crc32 多项式 生成 string 参数的 32 位循环冗余校验码多项式……:这句话从英文翻译过来的,不正确,准确的说应该是这么理解: 以32位循环冗余校验多项式 ...

  9. Linux下的Backlight子系统(二)【转】

    转自:http://blog.csdn.net/weiqing1981127/article/details/8515847 版权所有,转载必须说明转自 http://my.csdn.net/weiq ...

  10. Google开源命令行参数解析库gflags

    Google开源命令行参数解析库gflags http://blog.csdn.net/lming_08/article/details/25072899 CMDLINE的解析 http://blog ...