题意:

      给你起点终点,和一些加油站,和每次加油后的最大行驶距离,问你从起点到终点最少加油次数,要求两点之间必须走直线,见到加油站必须加油,也就是说如果想从a走到b,那么a,b连线上的加油站必须加油。

思路:

      关键就是处理a,b,之间的点必须加油这个问题,我们可以排序,x小的或者x相等y小的在前面,然后枚举每条边,对于每个点为起点的边如果当前的斜率出现过,那么我们就可以不加这条边(或者是在费用上增加1后加上这条边),不加的原因是我们可以再后面加,比如a -> b ->c 我们可以 a ->b ,然后b->c,(也可以a->c 距离+1),标记每一个点为起点的斜率,斜率出现过就不加了,标记斜率可以用容器,总的建图时间复杂度是

O(n*n*log(n)) log(n)是因为map操作需要一个log级的时间复杂度。


斜率相同直接跳过

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<map> #define N_node 1000 + 100
#define N_edge 1000000 + 1000
#define INF 0x3f3f3f3f

using namespace
std; typedef struct
{
int
to ,next ,cost;
}
STAR; typedef struct
{
double
x ,y;
int
id;
}
NODE; STAR E[N_edge];
NODE node[N_node];
int
list[N_node] ,tot;
int
s_x[N_node];
map<double ,int>hash; void add(int a ,int b ,int c)
{

E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot;
} double
dis(NODE a ,NODE b)
{
double
x = (a.x - b.x) * (a.x - b.x);
double
y = (a.y - b.y) * (a.y - b.y);
return
sqrt(x + y);
} bool
camp(NODE a ,NODE b)
{
return
a.x < b.x || a.x == b.x && a.y < b.y;
} void
spfa(int s ,int n)
{
int
mark[N_node] = {0};
for(int
i = 0 ;i <= n ;i ++)
s_x[i] = INF;
queue<int>q;
q.push(s);
mark[s] = 1 ,s_x[s] = 0;
while(!
q.empty())
{
int
xin ,tou;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int
k = list[tou] ;k ;k = E[k].next)
{
int
xin = E[k].to;
if(
s_x[xin] > s_x[tou] + E[k].cost)
{

s_x[xin] = s_x[tou] + E[k].cost;
if(!
mark[xin])
{

mark[xin] = 1;
q.push(xin);
}
}
}
}
} int main ()
{
int
n ,i ,j ,t;
double
L;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d %lf" ,&n ,&L);
scanf("%lf %lf" ,&node[1].x ,&node[1].y);
scanf("%lf %lf" ,&node[2].x ,&node[2].y);
node[1].id = 1 ,node[2].id = 2;
for(
n += 2 ,i = 3 ;i <= n ;i ++)
{

scanf("%lf %lf" ,&node[i].x ,&node[i].y);
node[i].id = i;
}

sort(node + 1 ,node + n + 1 ,camp);
for(
i = 1 ;i <= n ;i ++)
{

hash.clear();
for(
j = i + 1 ;j <= n ;j ++)
if(
dis(node[i] ,node[j]) <= L)
{
double
xx = node[j].x - node[i].x;
double
yy = node[j].y - node[i].y;
double
v = xx == 0 ? -INF : yy / xx;
if(
hash[v]) continue;
hash[v] = 1;
add(node[i].id ,node[j].id ,hash[v]);
add(node[j].id ,node[i].id ,hash[v]);
}
}

spfa(1 ,n);
int
ans = s_x[2];
ans == INF ? puts("impossible") : printf("%d\n" ,ans - 1);
}
return
0;
}


出现过的斜率那么就累加1的(跟上面的只有两行不同,其他的相同)

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<map> #define N_node 1000 + 100
#define N_edge 1000000 + 1000
#define INF 0x3f3f3f3f

using namespace
std; typedef struct
{
int
to ,next ,cost;
}
STAR; typedef struct
{
double
x ,y;
int
id;
}
NODE; STAR E[N_edge];
NODE node[N_node];
int
list[N_node] ,tot;
int
s_x[N_node];
map<double ,int>hash; void add(int a ,int b ,int c)
{

E[++tot].to = b;
E[tot].cost = c;
E[tot].next = list[a];
list[a] = tot;
} double
dis(NODE a ,NODE b)
{
double
x = (a.x - b.x) * (a.x - b.x);
double
y = (a.y - b.y) * (a.y - b.y);
return
sqrt(x + y);
} bool
camp(NODE a ,NODE b)
{
return
a.x < b.x || a.x == b.x && a.y < b.y;
} void
spfa(int s ,int n)
{
int
mark[N_node] = {0};
for(int
i = 0 ;i <= n ;i ++)
s_x[i] = INF;
queue<int>q;
q.push(s);
mark[s] = 1 ,s_x[s] = 0;
while(!
q.empty())
{
int
xin ,tou;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int
k = list[tou] ;k ;k = E[k].next)
{
int
xin = E[k].to;
if(
s_x[xin] > s_x[tou] + E[k].cost)
{

s_x[xin] = s_x[tou] + E[k].cost;
if(!
mark[xin])
{

mark[xin] = 1;
q.push(xin);
}
}
}
}
} int main ()
{
int
n ,i ,j ,t;
double
L;
scanf("%d" ,&t);
while(
t--)
{

scanf("%d %lf" ,&n ,&L);
scanf("%lf %lf" ,&node[1].x ,&node[1].y);
scanf("%lf %lf" ,&node[2].x ,&node[2].y);
node[1].id = 1 ,node[2].id = 2;
for(
n += 2 ,i = 3 ;i <= n ;i ++)
{

scanf("%lf %lf" ,&node[i].x ,&node[i].y);
node[i].id = i;
}

sort(node + 1 ,node + n + 1 ,camp);
memset(list ,0 ,sizeof(list)) ,tot = 1;
for(
i = 1 ;i <= n ;i ++)
{

hash.clear();
for(
j = i + 1 ;j <= n ;j ++)
if(
dis(node[i] ,node[j]) <= L)
{
double
xx = node[j].x - node[i].x;
double
yy = node[j].y - node[i].y;
double
v = (xx == 0 ? -INF : yy / xx);
//if(hash[v]) continue;
hash[v] ++;
add(node[i].id ,node[j].id ,hash[v]);
add(node[j].id ,node[i].id ,hash[v]);
}
}

spfa(1 ,n);
int
ans = s_x[2];
ans == INF ? puts("impossible") : printf("%d\n" ,ans - 1);
}
return
0;
}

hdu4885 有 限制的最短路的更多相关文章

  1. bzoj1001--最大流转最短路

    http://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路:这应该算是经典的最大流求最小割吧.不过题目中n,m<=1000,用最大流会TLE, ...

  2. 【USACO 3.2】Sweet Butter(最短路)

    题意 一个联通图里给定若干个点,求他们到某点距离之和的最小值. 题解 枚举到的某点,然后优先队列优化的dijkstra求最短路,把给定的点到其的最短路加起来,更新最小值.复杂度是\(O(NElogE) ...

  3. Sicily 1031: Campus (最短路)

    这是一道典型的最短路问题,直接用Dijkstra算法便可求解,主要是需要考虑输入的点是不是在已给出的地图中,具体看代码 #include<bits/stdc++.h> #define MA ...

  4. 最短路(Floyd)

    关于最短的先记下了 Floyd算法: 1.比较精简准确的关于Floyd思想的表达:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B.所以,我们假设maz ...

  5. bzoj1266最短路+最小割

    本来写了spfa wa了 看到网上有人写Floyd过了 表示不开心 ̄へ ̄ 改成Floyd试试... 还是wa ヾ(。`Д´。)原来是建图错了(样例怎么过的) 结果T了 于是把Floyd改回spfa 还 ...

  6. HDU2433 BFS最短路

    Travel Time Limit: 10000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  7. 最短路(代码来源于kuangbin和百度)

    最短路 最短路有多种算法,常见的有一下几种:Dijstra.Floyd.Bellman-Ford,其中Dijstra和Bellman-Ford还有优化:Dijstra可以用优先队列(或者堆)优化,Be ...

  8. Javascript优化细节:短路表达式

    什么是短路表达式? 短路表达式:作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程 ...

  9. Python中三目计算符的正确用法及短路逻辑

    今天在看别人代码时看到这样一种写法, 感觉是个挺容易踩到的坑, 搞清楚后写出来备忘. 短路逻辑 Python中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...

随机推荐

  1. a标签不能继承父级的颜色

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. ASP.NET Core中间件初始化探究

    前言 在日常使用ASP.NET Core开发的过程中我们多多少少会设计到使用中间件的场景,ASP.NET Core默认也为我们内置了许多的中间件,甚至有时候我们需要自定义中间件来帮我们处理一些请求管道 ...

  3. Java中的Set集合

    Set接口简介 Set接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,它是比Collecti ...

  4. 常用开发库 - 告別BeanUtils拷贝,MapStruct工具库最全详解

    常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...

  5. go-ini入门教程

    go-ini入门教程 go-ini简介 Package ini provides INI file read and write functionality in Go. 在实际开发时,配置信息一般不 ...

  6. AggregateReport V2.2.0

    1. 说明 AggregateReport V2.2.0终于跟大家见面了!从V1.0.0到V2.2.0 宝路听取了很多同学的建议!感谢大家一路的信任与支持! 2. 文章导读 如果不了解此工具的同学,建 ...

  7. Hi3559AV100 NNIE开发(7) Ruyistudio 输出mobileface_func.wk与板载运行mobileface_chip.wk输出中间层数据对比

    前面随笔讲了关于NNIE的整个开发流程,并给出了Hi3559AV100 NNIE开发(5)mobilefacenet.wk仿真成功量化及与CNN_convert_bin_and_print_featu ...

  8. vue 快速入门 系列 —— 初步认识 vue

    其他章节请看: vue 快速入门 系列 初步认识 vue vue 是什么 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架. 所谓渐进式,就是你可以一步一步.有阶段 ...

  9. Python中切片的应用

    Python中切片的应用 Python中可以通过切片实现对列表或者字符串取指定范围的操作,实际就是通过对列表或者字符串通过索引进行操作. 具体细节点击廖雪峰Python教程,其中的课后小问题在此记录下 ...

  10. java面试-G1垃圾收集器

    一.以前收集器的特点 年轻代和老年代是各自独立且连续的内存块 年轻代收集器使用 eden + S0 + S1 进行复制算法 老年代收集必须扫描整个老年代区域 都是以尽可能的少而快速地执行 GC 为设计 ...