hdu4885 有 限制的最短路
题意:
给你起点终点,和一些加油站,和每次加油后的最大行驶距离,问你从起点到终点最少加油次数,要求两点之间必须走直线,见到加油站必须加油,也就是说如果想从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 有 限制的最短路的更多相关文章
- bzoj1001--最大流转最短路
http://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路:这应该算是经典的最大流求最小割吧.不过题目中n,m<=1000,用最大流会TLE, ...
- 【USACO 3.2】Sweet Butter(最短路)
题意 一个联通图里给定若干个点,求他们到某点距离之和的最小值. 题解 枚举到的某点,然后优先队列优化的dijkstra求最短路,把给定的点到其的最短路加起来,更新最小值.复杂度是\(O(NElogE) ...
- Sicily 1031: Campus (最短路)
这是一道典型的最短路问题,直接用Dijkstra算法便可求解,主要是需要考虑输入的点是不是在已给出的地图中,具体看代码 #include<bits/stdc++.h> #define MA ...
- 最短路(Floyd)
关于最短的先记下了 Floyd算法: 1.比较精简准确的关于Floyd思想的表达:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B.所以,我们假设maz ...
- bzoj1266最短路+最小割
本来写了spfa wa了 看到网上有人写Floyd过了 表示不开心 ̄へ ̄ 改成Floyd试试... 还是wa ヾ(。`Д´。)原来是建图错了(样例怎么过的) 结果T了 于是把Floyd改回spfa 还 ...
- HDU2433 BFS最短路
Travel Time Limit: 10000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- 最短路(代码来源于kuangbin和百度)
最短路 最短路有多种算法,常见的有一下几种:Dijstra.Floyd.Bellman-Ford,其中Dijstra和Bellman-Ford还有优化:Dijstra可以用优先队列(或者堆)优化,Be ...
- Javascript优化细节:短路表达式
什么是短路表达式? 短路表达式:作为"&&"和"||"操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程 ...
- Python中三目计算符的正确用法及短路逻辑
今天在看别人代码时看到这样一种写法, 感觉是个挺容易踩到的坑, 搞清楚后写出来备忘. 短路逻辑 Python中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...
随机推荐
- a标签不能继承父级的颜色
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- ASP.NET Core中间件初始化探究
前言 在日常使用ASP.NET Core开发的过程中我们多多少少会设计到使用中间件的场景,ASP.NET Core默认也为我们内置了许多的中间件,甚至有时候我们需要自定义中间件来帮我们处理一些请求管道 ...
- Java中的Set集合
Set接口简介 Set接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,它是比Collecti ...
- 常用开发库 - 告別BeanUtils拷贝,MapStruct工具库最全详解
常用开发库 - MapStruct工具库详解 MapStruct是一款非常实用Java工具,主要用于解决对象之间的拷贝问题,比如PO/DTO/VO/QueryParam之间的转换问题.区别于BeanU ...
- go-ini入门教程
go-ini入门教程 go-ini简介 Package ini provides INI file read and write functionality in Go. 在实际开发时,配置信息一般不 ...
- AggregateReport V2.2.0
1. 说明 AggregateReport V2.2.0终于跟大家见面了!从V1.0.0到V2.2.0 宝路听取了很多同学的建议!感谢大家一路的信任与支持! 2. 文章导读 如果不了解此工具的同学,建 ...
- Hi3559AV100 NNIE开发(7) Ruyistudio 输出mobileface_func.wk与板载运行mobileface_chip.wk输出中间层数据对比
前面随笔讲了关于NNIE的整个开发流程,并给出了Hi3559AV100 NNIE开发(5)mobilefacenet.wk仿真成功量化及与CNN_convert_bin_and_print_featu ...
- vue 快速入门 系列 —— 初步认识 vue
其他章节请看: vue 快速入门 系列 初步认识 vue vue 是什么 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架. 所谓渐进式,就是你可以一步一步.有阶段 ...
- Python中切片的应用
Python中切片的应用 Python中可以通过切片实现对列表或者字符串取指定范围的操作,实际就是通过对列表或者字符串通过索引进行操作. 具体细节点击廖雪峰Python教程,其中的课后小问题在此记录下 ...
- java面试-G1垃圾收集器
一.以前收集器的特点 年轻代和老年代是各自独立且连续的内存块 年轻代收集器使用 eden + S0 + S1 进行复制算法 老年代收集必须扫描整个老年代区域 都是以尽可能的少而快速地执行 GC 为设计 ...