题意:

      给你起点终点,和一些加油站,和每次加油后的最大行驶距离,问你从起点到终点最少加油次数,要求两点之间必须走直线,见到加油站必须加油,也就是说如果想从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. 剑指 Offer 22. 链表中倒数第k个节点

    剑指 Offer 22. 链表中倒数第k个节点 Offer 22 常规解法 常规解法其实很容易可以想到,只需要先求出链表的长度,然后再次遍历取指定长度的链接即可. package com.walega ...

  2. HDOJ-1257(贪心/动态规划)

    最少拦截系统 HDOJ-1257 我做这题的思路就是采用暴力或者贪心.也就是每次循环选出从第一个未被选择的元素开始,依次把后面可以选择的元素作为一个系统.最后统计可以有多少个系统. 还有人的思路就是利 ...

  3. js浅拷贝(地址引用)和深拷贝(克隆)

    浅拷贝和深拷贝相对于引用类型而言的. js有两大类型值类型(基本数据类型)和引用类型(object,function,array): 值类型保存在栈上,引用类型保存在堆上. 浅拷贝只是单纯的拷贝对象的 ...

  4. Codeforces Round #684 (Div. 2)

    A 讨论三种情况,不换/全换成0/全换成1 ,取一个花费最小值 #include <bits/stdc++.h> using namespace std; const int N = 10 ...

  5. PHP配置 3. 配置open_basedir

    open_basedir将网站限定在指定的目录,做目录的隔离 先在php.ini中设置open_basedir: # vim /usr/local/php/etc/php.ini //搜索open_b ...

  6. 计算异质性H值(运用arcgis和Python进行区域分析)

    最近需要对ecognition分割结果进行统计分析,以此来进一步判断其分割结果中的欠分割和过分割对象,在看了一篇论文后,发现了可以用一个参数H来判断每个切割对象的异质性,由于此方法需要用到arcgis ...

  7. SPOJ D-query 【主席树】

    一 题目 D-query 二 分析 主席树的运用. 这题首先应该考虑的是,如何分出种类数?再就是考虑如何维护区间信息? 最开始想的是直接离散化后用权值线段树建主席树,发现不行,因为假如$ [l,r] ...

  8. get和post的区别主要有以下几方面

    1.url可见性: get,参数url可见: post,url参数不可见 2.数据传输上: get,通过拼接url进行传递参数: post,通过body体传输参数 3.缓存性: get请求是可以缓存的 ...

  9. 用程序员的思维了解Filecoin

    程序员接触一个新技术惯用步骤: 先搜索引擎搜索一波,找个最简单的解释.如果有了个大概的概念,就前往2.否则循环1->1->1...直到有个大概的概念为止. 上官网跑一遍. 各种论坛社区溜达 ...

  10. MySQL常用配置参数说明

    1.sync_binlog sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来 ...