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中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...
随机推荐
- Java程序员必备后台前端框架--Layui【从入门到实战】(一)
layui入门使用及图标的使用 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] [编程工具:IDEA] 下载Layui与文件分析 下载直接去官网下载即可 文件分析 下载完成后,解压会 ...
- ACM STU week3
STU ACM训练week3(2.5-2.15) By@Xiezeju 训练计划的CP4配套资源库 训练时间安排 定期任务 任务 每日 进行1小时的盲打训练锻练手速 打字网站,最好注册账号以保存进度 ...
- CVE-2017-12615 -Tomcat-任意写入文件
漏洞分析参考 https://www.freebuf.com/vuls/148283.html 漏洞描述: 当 Tomcat运行在Windows操作系统时,且启用了HTTP PUT请求方法(例如,将 ...
- java注解基础入门
前言 这篇博客主要是对java注解相关的知识进行入门级的讲解,包括**,核心内容主要体现在对java注解的理解以及如何使用.希望通过写这篇博客的过程中让自己对java注解有更深入的理解,在工作中可以巧 ...
- 14、MyBatis教程之全部(包括所有章节)
MyBatis 3.5.5 教程 1.环境准备 jdk 8 + MySQL 5.7.19 maven-3.6.1 IDEA 学习前需要掌握: JDBC MySQL Java 基础 Maven Juni ...
- 浅析MyBatis(四):全自动写代码的MyBatis逆向工程
在前面几篇文章中,笔者介绍了 MyBatis 的运行流程,在此基础上简单介绍了手写 MyBatis 简易框架与自定义 MyBatis 插件的步骤,相信大家对于 MyBatis 框架的使用流程已经游刃有 ...
- JAVA题目:正整数n若是其平方数的尾部,则称n为同构数 如:5*5=25, 25*25=625 问: 求1~99中的所有同构数
1 /*题目:正整数n若是其平方数的尾部,则称n为同构数 2 如:5*5=25, 25*25=625 3 问: 求1~99中的所有同构数 4 */ 5 //分析:将1-99分为1-9和10-99,用取 ...
- SQL注入靶场实战-小白入门
目录 SQL注入 数字型 1.测试有无测试点 2.order by 语句判断字段长,查出字段为3 3.猜出字段位(必须与内部字段数一致)(用union联合查询查看回显点为2,3) 4.猜数据库名,用户 ...
- 「HTML+CSS」--自定义加载动画【009】
前言 Hello!小伙伴! 首先非常感谢您阅读海轰的文章,倘若文中有错误的地方,欢迎您指出- 哈哈 自我介绍一下 昵称:海轰 标签:程序猿一只|C++选手|学生 简介:因C语言结识编程,随后转入计算机 ...
- Node.js 包管理器 NPM 讲解
包管理器又称软件包管理系统,它是在电脑中自动安装.配制.卸载和升级软件包的工具组合,在各种系统软件和应用软件的安装管理中均有广泛应用.对于我们业务开发也很受益,相同的东西不必重复去造轮子. 每个工具或 ...