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中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...
随机推荐
- HDOJ-1114(完全背包模板题)
Piggy-Bank HDOJ-1114 本题就是完全背包的模板题,注意复习一下关于背包九讲中的问什么这里使用的是顺序遍历. 还需要注意的一个问题就是初始化的问题,dp[0]初始化为0,其他的初始化为 ...
- Android+Chrome 真机调试H5页面实践
前言 使用weinre在真机上调试H5页面,有一个突出的缺点,就是无法调试真机上的样式,真机上页面动态创建的dom在weinre的Elements面板显示不出来,所以调试真机上的页面样式也就无从谈起. ...
- 如何在 Istio 中支持 Dubbo、Thrift、Redis 以及任何七层协议?
赵化冰,腾讯云高级工程师,Istio Member,ServiceMesher管理委员,Istio 项目贡献者, Aerika 项目创建者 ,热衷于开源.网络和云计算.目前主要从事服务网格的开源和研发 ...
- 关于主机不能访问虚拟机的web服务解决
centos7默认并没有开启80端口,我们只有开启就行 [root@localhost sysconfig]# firewall-cmd --permanent --add-port=3032/tcp ...
- [unknown source] 整数拆分
一.题目 题目描述 定义一个整数拆分序列 \(a\) 的权值为: \[\sum_{i=1}^n\sum_{j=1}^{i-1}\gcd(a_i,a_j) \] 求对于一个整数 \(n\) 所有整数拆分 ...
- [LOJ 572] Misaka Network 与求和
一.题目 点此看题 二.解法 直接推柿子吧: \[\sum_{i=1}^n\sum_{j=1}^nf(\gcd(i,j))^k \] \[\sum_{d=1}^nf(d)^k\sum_{i=1}^{n ...
- Python装饰器(3)
这篇文章中记录说明下多个装饰器一同装饰同一个函数时的执行顺序问题. [装饰器链] 按照惯例,先看代码示例: import time def debug1(str): #传参接受类的方法 def fun ...
- 通过 Battery Historian 工具分析 Android APP 耗电情况
电量统计模块概述 Android 从两个层面统计电量的消耗,分别为 软件排行榜 及 硬件排行榜.它们各有自己的耗电榜单,软件排行榜为机器中每个 App 的耗电榜单,硬件排行榜则为各个硬件的耗电榜单.这 ...
- python-递归函数和内置函数笔记汇总
1. def syz(*args) # *args 参数组 不必填,不限制参数的个数 参数组不常用 2.def sys2(**kwargs): #关键字参数 3.递归函数, 不常 ...
- PTA 二叉树的三种遍历(先序、中序和后序)
6-5 二叉树的三种遍历(先序.中序和后序) (6 分) 本题要求实现给定的二叉树的三种遍历. 函数接口定义: void Preorder(BiTree T); void Inorder(BiTr ...