最短路(hdu4725)(建点巧妙)
传送门
题目大意是:
有一些点,分为几层,然后层与层之间可花费代价C到达,还有一些特殊边,使得某个点和某个点之间花费某代价可以到达,求从1到n的最小代价。
一开始的想法是,既然层与层之间可以到达,那么对于第i层和第i+1层,把第i层的所有点与第i+1层的所有点连边,权值为C,特殊的边该怎么连怎么连,然后跑最短路。
然后我看了一下数据范围——N, M (0 <= N, M <= 105) 笑不出来
好吧,那让我们考虑一下如何优化。
我们知道,同一层内的点是可以相互到达的且无花费。也就是说,如果我想去到第i层,我到达第i层的某个点后就相当于我到了这一层中所有的点。
那么对于每一层,我可以建一个入点和一个出点(或者说就建一个点也行,反正连进和连出的边的性质是一样的)。层与层之间就有建的点相连(代价就为C),层内的点全部连向建的点(代价为0)。
连变数:2*n+m 时间O(e loge)能过
注意:1.建的虚拟点的编号一定不要和原来的点重复了。2.图中的点不再是n个,而应该建成3n个
#include <cstdio> #include <vector> #include <queue> #include <cstring> #define N 100003 #define M 100003 using namespace std; int read() {int f=1,x=0;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}return x*f; } const int INF=0x3f3f3f3f; struct qnode {int v;int c;qnode(int _v=0,int _c=0):v(_v),c(_c){}bool operator <(const qnode &r)const{return c>r.c;} }; struct Edge {int v,cost;Edge(int _v=0,int _cost=0):v(_v),cost(_cost){} }; vector<Edge> E[N*2+M]; bool vis[N*3]; int dist[N*3];void dij(int n,int start)//点的编号从1开始 {memset(vis,false,sizeof(vis));for(int i=1;i<=n;i++) dist[i]=INF;priority_queue<qnode> que;while(!que.empty()) que.pop();dist[start]=0;que.push(qnode(start,0));qnode tmp;while(!que.empty()){tmp=que.top();que.pop();int u=tmp.v;if(vis[u]) continue;vis[u]=true;for(int i=0;i<E[u].size();i++){int v=E[tmp.v][i].v;int cost=E[u][i].cost;if(!vis[v]&&dist[v]>dist[u]+cost){dist[v]=dist[u]+cost;que.push(qnode(v,dist[v]));}}} }void add(int u,int v,int w) {E[u].push_back(Edge(v,w)); } int main() {int T=read();for(int k=1;k<=T;++k){for(int i=0;i<=N*2+M;i++)if(!E[i].empty())E[i].clear();int n=read(),m=read(),c=read();for(int i=1;i<=n;++i){int x=read();add(x*2+n-1,i,0);add(i,x*2+n,0);}for(int i=1;i<=m;++i){int u=read(),v=read(),w=read();add(u,v,w);add(v,u,w);}for(int i=1;i<=n;++i){int u=2*i+n;if(i>1)add(u,u-3,c);if(i<n)add(u,u+1,c);}dij(3*n,1);printf("Case #%d: %d\n",k,(dist[n]==INF?-1:dist[n]));} } /* */
最短路(hdu4725)(建点巧妙)
转载于:https://www.cnblogs.com/yyys-/p/11172799.html
最短路(hdu4725)(建点巧妙)相关推荐
- HDU4725 SPFA (最短路+层级建图)
问题描述 这是一个非常容易的问题,你的任务只是计算el camino mas corto en un grafico,而且只是单独干草阙cambiar un poco el algoritmo.如果你 ...
- 算法提高课-图论-单源最短路的建图方式-AcWing 903. 昂贵的聘礼:建图巧妙、dijkstra、考虑等级
题目分析 来源:acwing 由于终点是1号节点,建立虚拟节点S,如下建图(根据样例画图).S出发和每个点直连的边权代表直接买该物品花的金币数:而由S到1的任意一条通路,边权之和就是花费的金币数.所以 ...
- 算法提高课-图论-单源最短路的建图方式-AcWing 920. 最优乘车:bfs求最短路、建图
题目分析 来源:acwing 分析: 本题难在抽象建图上,这里采用的建图方式是:同一条公交线路上,前面的站点都可以连一条有向边到其后面的站点,且边权都为1. 由于边权都是1,可以用bfs来求最短路. ...
- CodeForces - 1529F It‘s a bird! No, it‘s a plane! No, it‘s AaParsa!(最短路+思维建图)
题目链接:点击查看 题目大意:给出 nnn 个点(从 000 开始编号)和 mmm 条边的有向带权图,不过 mmm 条边是动态的,经过 ttt 秒后,第 iii 条边就从 ai−>bi,cia_ ...
- HDU 4725 层级最短路 思维建图 邻接表 堆优化迪杰斯特拉 真的难想 区域网络赛真题
题目 题解思路 知道是最短路,怎么建图呢? 一开始想到每层来一个超级源点,但是方向不知道怎么确定,用双向边果然WA了(如果是双向边,那一层的都会变成0费连通了 ). 翻了翻 大佬的博客 大佬定义了一种 ...
- 小雨坐地铁--[最短路分层建图+虚点]
也是第一次接触这种分层建图的最短路 思路:由题目我们可以知道某些站点是可以连接好几条地铁线路的,那么对于每条地铁线路我们可以把他当成一幅图来算.当然图是个无向图,所以要加两次边. add(i*n+x, ...
- 【Gym - 101986F】Pizza Delivery(Dijkstra最短路,建图方式,反向建图,Tarjan求桥,图论模板)
题干: 题目大意: 一个有向图,编号1~n的n个点,m条边,规定1为起点,2为终点,问对于每一条边,反转它的方向,最短路会不会发生改变,如果变短了,输出HAPPY,变长了或者到达不了了输出SAD,不变 ...
- AcWing 1132. 农场派对(最短路反向建边)
题目链接 https://www.acwing.com/problem/content/1134/ http://poj.org/problem?id=3268 思路 我们想求所有点到x的距离以及x到 ...
- 单源最短路的建图方式(Dijkstra)
由于是复习,所以不会解释太多. 主要为Dijkstra的堆优化板子和朴素版(看数据范围) 再次看看时间复杂度[ n 为点数,m 为边数 ]:朴素版:O(),堆优化版:O( (n+m)logm ). 目 ...
最新文章
- js轮播图代码_javascript基础(一)——轮播图
- JVM-09自动内存管理机制【内存分配和回收策略】
- 如何在7分钟内黑掉40家网站?
- selenium之 chromedriver版本对照表
- iOS 苹果app提交 ITC.apps.validation.prerelease_build_missing
- 计算机软件应用控制程序,一种计算机应用程序实时控制软件的制作方法
- Assets.car 解压工具 cartool 使用报错 segmentation fault cartool 解决方案
- ORACLE 数据库的级联查询 一句sql搞定(部门多级)
- 内存管理之直接内存管理
- opencv的lena项目,用android studio 3.6可以运行——drawable如何引入lena图片
- 《教程》使用STLINK烧录STM32程序
- Aqua Comms携手Ciena 测试海底光缆网络150Gbps波长传输
- 支付系统---银行卡收单业务
- Golang chan的任务分发和优雅退出
- IKVM.NET_第三篇_成功项目
- Vue -Ts入门 (一)
- setting多仓库写法
- 如何解决hao.123.com的挟持网页(篡改网站主页)
- android 新闻功能列表,news: 用Android基本技术实现的新闻App
- uva10635 Prince and Princess LCS 变 lIS