题目链接:点击查看

题目大意:给出一个 n * n 的二维平面,现在要从点 ( sx , sy ) 到达点 ( fx , fy ),在平面上有 m 个传送门,共有两次操作:

  1. 向上、下、左、右移动一个单位,花费为一个单位
  2. 可以瞬间移动到同行或同列的传送门,没有花费

现在问从起点到终点最少需要多少时间

题目分析:首先需要知道的是,起点和终点并不是传送门,所以最后的一步一定是要么从起点走到终点,要么是从传送门走到终点

所以问题转换为了如何在传送门之间建图,不难发现如果 x 坐标相同或者 y 坐标相同的传送门都是可以无花费且相互可达的,而 x 轴或 y 轴不同的传送门,其之间的距离实质上就是两条坐标轴之间的距离,至多有 m 条 x 轴和 m 条 y 轴需要处理,离散化一下建图就好了

也不知道计算过程中会不会爆 int ,就直接开了 long long

代码:

//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<list>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;//顶点数 const int M=1e6+100;//边数 vector<pair<int,int>>node;vector<int>X,Y;template<typename T>
struct Dij
{const static int N=1e6+100;const static int M=1e6+100;struct Edge{int to,next;T w;}edge[M];int head[N],cnt;//链式前向星 T d[N];bool vis[N];void addedge(int u,int v,T w){edge[cnt].to=v;edge[cnt].w=w;edge[cnt].next=head[u];head[u]=cnt++;edge[cnt].to=u;edge[cnt].w=w;edge[cnt].next=head[v];head[v]=cnt++;}struct Node{int to;T w;Node(int TO,T W){to=TO;w=W;}bool operator<(const Node& a)const{return w>a.w;}};void Dijkstra(int st){priority_queue<Node>q;memset(vis,false,sizeof(vis));memset(d,0x3f,sizeof(d));d[st]=0;q.push(Node(st,0));while(q.size()){Node cur=q.top();int u=cur.to;q.pop();if(vis[u])continue;vis[u]=true;for(int i=head[u];i!=-1;i=edge[i].next)//扫描出所有边 {int v=edge[i].to;T w=edge[i].w;if(d[v]>d[u]+w)//更新 {d[v]=d[u]+w;q.push(Node(v,d[v]));}}}}void init(){memset(head,-1,sizeof(head));cnt=0; }
};Dij<LL>t;int get_id_x(int x)
{return lower_bound(X.begin(),X.end(),x)-X.begin()+node.size();
}int get_id_y(int y)
{return lower_bound(Y.begin(),Y.end(),y)-Y.begin()+node.size()+X.size();
}void discreate()
{sort(X.begin(),X.end());sort(Y.begin(),Y.end());X.erase(unique(X.begin(),X.end()),X.end());Y.erase(unique(Y.begin(),Y.end()),Y.end());for(int i=1;i<X.size();i++)t.addedge(i+node.size()-1,i+node.size(),X[i]-X[i-1]);for(int i=1;i<Y.size();i++)t.addedge(i+node.size()+X.size()-1,i+node.size()+X.size(),Y[i]-Y[i-1]);
}int main()
{
#ifndef ONLINE_JUDGE
//  freopen("data.in.txt","r",stdin);
//  freopen("data.out.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);t.init();int n,m;scanf("%d%d",&n,&m);int sx,sy,fx,fy;scanf("%d%d%d%d",&sx,&sy,&fx,&fy);node.emplace_back(sx,sy);node.emplace_back(fx,fy);X.push_back(sx);Y.push_back(sy);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);X.push_back(x);Y.push_back(y);node.emplace_back(x,y);}discreate();for(int i=0;i<node.size();i++){if(i==1)//如果是终点的话就不需要与传送门连边了continue;int x,y;tie(x,y)=node[i];t.addedge(get_id_x(x),i,0);t.addedge(get_id_y(y),i,0);t.addedge(i,1,abs(x-fx)+abs(y-fy));//每个点都需要与终点单独连一下边}t.Dijkstra(0);printf("%lld\n",t.d[1]);return 0;
}

CodeForces - 1422D Returning Home(最短路+思维建图)相关推荐

  1. CodeForces - 1529F It‘s a bird! No, it‘s a plane! No, it‘s AaParsa!(最短路+思维建图)

    题目链接:点击查看 题目大意:给出 nnn 个点(从 000 开始编号)和 mmm 条边的有向带权图,不过 mmm 条边是动态的,经过 ttt 秒后,第 iii 条边就从 ai−>bi,cia_ ...

  2. HDU 4725 层级最短路 思维建图 邻接表 堆优化迪杰斯特拉 真的难想 区域网络赛真题

    题目 题解思路 知道是最短路,怎么建图呢? 一开始想到每层来一个超级源点,但是方向不知道怎么确定,用双向边果然WA了(如果是双向边,那一层的都会变成0费连通了 ). 翻了翻 大佬的博客 大佬定义了一种 ...

  3. 男生和女生(思维建图,最大独立集问题)

    男生和女生(思维建图,最大独立集问题) 问题描述 在大学二年级,一些人开始了同学之间罗曼蒂克关系的研究.有"罗曼蒂克"关系是针对男生和女生之间的关系而言的.研究的原因是找到满足以下 ...

  4. POJ - 1847 Tram 最短路,思维建图

    题目链接 POJ-1847 题意 给定n节点,节点之间有道路相连,但是每个节点都有个开关,只有开关指向的节点才能通行,你可以搬动开关.给定起点终点,求最少搬动开关次数. 解法 建图,对于每个节点,初始 ...

  5. HDU - 5521 Meeting(最短路+思维建边)

    题目链接:点击查看 题目大意:给出 n 个点,再给出 m 个集合,对于每个集合中的点来说,其两两都是相互可达的,且花费都相同,问有多少个点,到达点 1 和点 n 的距离相同且最小 题目分析:因为每个集 ...

  6. 小雨坐地铁--[最短路分层建图+虚点]

    也是第一次接触这种分层建图的最短路 思路:由题目我们可以知道某些站点是可以连接好几条地铁线路的,那么对于每条地铁线路我们可以把他当成一幅图来算.当然图是个无向图,所以要加两次边. add(i*n+x, ...

  7. 算法提高课-图论-单源最短路的建图方式-AcWing 920. 最优乘车:bfs求最短路、建图

    题目分析 来源:acwing 分析: 本题难在抽象建图上,这里采用的建图方式是:同一条公交线路上,前面的站点都可以连一条有向边到其后面的站点,且边权都为1. 由于边权都是1,可以用bfs来求最短路. ...

  8. 单源最短路的建图方式(Dijkstra)

    由于是复习,所以不会解释太多. 主要为Dijkstra的堆优化板子和朴素版(看数据范围) 再次看看时间复杂度[ n 为点数,m 为边数 ]:朴素版:O(),堆优化版:O( (n+m)logm ). 目 ...

  9. abc302 F 思维建图+dij

    题意:给你n个集合,如果两个集合有公共元素,那么就可以合并,问你最小合并几次可以得到一个集合包含1和m. 思路:非常经典的套路建图,就是将集合和集合中的元素为两端,来建图.集合中的元素到集合的边权为1 ...

最新文章

  1. 没错,老板让我写个 BUG!
  2. Google 出品的 Java 编码规范,值得借鉴!
  3. 2021-07-05 操作系统实操相关知识点笔记--中断、异常的响应和处理
  4. 砸115亿元入局!后知后觉的欧洲重金建设AI,为赶中超美
  5. 训练加速3倍!字节跳动推出业界首个NLP模型全流程加速引擎
  6. Redis设计与实现-集群
  7. visio添加多分枝连接线
  8. FINSTCP python2.5
  9. 中国身份证号码验证,支持15,18位
  10. 真的明白Code、RO-data、RW-data和ZI-data吗?
  11. 与电影同行的日子(同步更新)
  12. 外研在线:如何用云技术优化教育服务
  13. 光学心率传感器工作原理
  14. Product-based Neural Networks (PNN) - 改进特征交叉的方式
  15. 不知道PDF转PPT转换器哪个好用?分享三个简单好用的办公用具
  16. Java基础数据类型二进制转换
  17. 家装有必要用阻燃电线吗?
  18. 我在CSDN发表原创文章,被别人拿去发了一篇北大核心,论文难道就是东拼西凑?
  19. NYOJ-33-蛇形填数
  20. java 导出mdb文件_Java中Java生成mdb文件工具类

热门文章

  1. java16下载_java lombok下载
  2. linux mysql 5.6.24_Mysql实例Linux安装MySQL5.6.24使用文字说明
  3. 什么时候你应该用JSON Web Token
  4. Nacos分布式应用配置管理
  5. SpringSecurity OAuth2中表结构说明
  6. 使用Zookeeper实现leader选举
  7. plsql(轻量版)_游标的使用2
  8. 设计模式之_Iterator_02
  9. 计算机博士专业学位,河海大学计算机应用技术博士专业学位研究生培养方案
  10. from mysql_MySQL的FROM