题目分析


来源:acwing

分析:
道路:双向,边权非负,
航线:单向,边权可正可负,且无环。

根据题意,点可以分为很多团(连通块),团内部只有道路(道路是双向的,而且是连通的,所以不能存在航线,否则有环,矛盾);而航线是在团与团之间。航向满足什么呢? 团与团之间的航线也是无环的,是满足拓扑序的。所以,团与团之间是有向无环图。

本题:

  1. 如果边权非负,可以用dijkstra算法。时间复杂度是O(mlogn)
  2. 如果是拓扑图,不管边权是正是负,均可按拓扑序扫描,时间复杂度是线性的。

思路是:先把每个团看成1个点,用拓扑序扫描来处理;然后对于每个团,内部使用dijkstra算。

  1. 先读入所有双向道路,然后dfs所有连通块,计算两个数组:
    id[]:存储每个点属于哪个连通块;
    vector< int> block[]:存储每个连通块里有哪些点
  2. 输入所有航线,同时统计出每个连通块的入度。
  3. 按照拓扑序依次处理每个连通块。先将所有入度为0的连通块的编号加入队列。
  4. 每次从队头取出一个连通块的编号bid
  5. 将该block[bid]中的所有点加入堆中,然后对堆中的所有点跑dijkstra算法。
  6. 每次取出堆中距离最小的点ver。
  7. 然后遍历所有与ver相邻的点j。
    如果id[ver] == id[j],如果j能被更新,则把j插入到堆中;
    如果id[ver] != id[j],则将id[j] 这个连通块的入度-1,如果减到0,则将其插入到拓扑排序的队列中。

ac代码

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int  N = 25010, M = 150010;
const int  INF = 0x3f3f3f3f;
int n, mr, mp, S;
int h[N],e[M],w[M],ne[M],idx;
int id[N]; //每个点属于哪个连通块
vector<int> block[N]; // 每个连通块中有哪些点
int bcnt; // 连通块的个数
int dist[N];
bool st[N];
int din[N];// 每个连通块的入度queue<int> q;void add(int a, int b, int c){e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++;
}// 把连通的点放到连通块中
void dfs(int u, int bid){id[u] = bid; // u这点放到bid这个block中block[bid].push_back(u);// 遍历连通的所有临边for(int i = h[u]; ~i; i = ne[i]){int j = e[i];if(!id[j]) dfs(j, bid); // 都放到bid这个连通块中}}// 求每个连通块内部的最短路
void dijkstra(int bid){priority_queue<PII, vector<PII>, greater<PII>> heap;for(auto ver : block[bid]) heap.push({dist[ver],ver});while(heap.size()){auto t = heap.top();heap.pop();int ver = t.y, distance = t.x;if(st[ver]) continue;st[ver] = true;for(int i = h[ver]; ~i; i = ne[i]){int j = e[i];if(dist[j] > dist[ver] + w[i]){dist[j] = dist[ver] + w[i];if(id[j] == id[ver]) heap.push({dist[j], j});}if(id[j] != id[ver] && -- din[id[j]] == 0)q.push(id[j]);}}
}void topsort(){memset(dist, 0x3f, sizeof dist);dist[S] = 0;for(int i = 1; i <= bcnt; i ++){if(!din[i])q.push(i); // 把入度为零的连通块加入队列中}while(q.size()){int t = q.front();q.pop();dijkstra(t); //对编号为t的连通块进行dijkstra}}int main(){cin >> n >> mr >> mp >> S;memset(h, -1, sizeof h);while(mr --){int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c), add(b, a, c);}// 所有的点分类到不同的连通块// 放在id[]数组中for(int i = 1; i <= n; i ++){if(!id[i])dfs(i, ++ bcnt); }// 读入航线while(mp --){int a, b, c;scanf("%d%d%d",&a, &b, &c);add(a, b, c);din[id[b]] ++; // 后者所在连通块的入度+1}topsort();for(int i = 1; i <= n; i ++)if(dist[i] > INF/ 2) puts("NO PATH");else printf("%d\n", dist[i]);
}

题目来源

https://www.acwing.com/problem/content/344/

算法提高课-图论-单源最短路的综合应用-AcWing 342. 道路与航线:最短路dijkstra、拓扑排序 、综合题、好题相关推荐

  1. 算法提高课-图论-单源最短路的综合应用-AcWing 1135. 新年好:dijkstra和dfs暴搜结合

    题目分析 来源:acwing 分析: 先预处理出从1,a,b,c,d,e出发到其他所有点的单源最短路.存在二维数组dist[6][N]中 dfs暴搜所有拜访顺序,共有5!种,对于每一种拜访顺序,可以通 ...

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

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

  3. 算法提高课-图论-单源最短路的建图方式-AcWing 1127. 香甜的黄油:spfa最短路

    题目分析 来源:acwing 分析: 多源汇最短路.所以我们首先想到的是floyd算法, 可是它的复杂度是O(n3)O(n^3)O(n3),会超时.所以我们需要另外考虑. 任意一个点作为起点求出到所有 ...

  4. 算法提高课-图论-单源最短路的建图方式-AcWing 903. 昂贵的聘礼:建图巧妙、dijkstra、考虑等级

    题目分析 来源:acwing 由于终点是1号节点,建立虚拟节点S,如下建图(根据样例画图).S出发和每个点直连的边权代表直接买该物品花的金币数:而由S到1的任意一条通路,边权之和就是花费的金币数.所以 ...

  5. 算法提高课-图论-单源最短路的建图方式-AcWing 1128. 信使:dijkstra、 最短路取最大值

    题目分析 来源:acwing 分析:广播模型,求整个网络所有点都被广播到,需要多少时间. 本题核心:对于每个点来说,它接收到信的时间,是等于它到指挥部的最短距离. 所以,所有点被广播到,就是求指挥部到 ...

  6. 算法提高课-图论-单源最短路的扩展应用-AcWing 1137. 选择最佳线路:多源最短路、虚拟源点

    题目分析 来源:acwing 分析: 本题有多组测试数据,如果对每个源点暴力使用dijkstra,会超时. 好的做法:建立虚拟源点S,让S到所有真实起点的边权为0,这样原问题就可以转换为从虚拟源点S到 ...

  7. 算法提高课-图论-单源最短路的建图方式-AcWing 1126. 最小花费:dijkstra求最长路

    题目分析 来源:acwing 分析: 链条转移:start * (1-w1) * (1- w2) * (1- w3) -(1-wn) = 100,要start最小,则w =(1-w1) * (1- w ...

  8. 算法提高课-图论-单源最短路的建图方式-AcWing 1129. 热浪:dijkstra裸题

    题目分析 来源:acwing 分析: ac代码 朴素的dijkstra() ,时间复杂度O(n2)O(n^2)O(n2) #include<bits/stdc++.h> using nam ...

  9. 算法提高课-图论-有向图的强连通分量-AcWing 367. 学校网络:强连通分量、tarjan算法

    文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 第一问:通过tarjan算法求出强连通分量并且缩点后,统计入度为0的点的个数p即可. 第二问,至少加几条边才能使图变成强连通分量?这 ...

最新文章

  1. 深度解析:特斯拉的工厂为什么建造得这么快?
  2. [转]Creating Unit Tests for ASP.NET MVC Applications (C#)
  3. C#学习基本概念之关键字---delegate(委托)
  4. Nest Secure智能保全系统内建麦克风 引发用户反弹
  5. 幻灯片演示什么模式最好_清洁单元测试图案–演示幻灯片
  6. PHP短网址链接在线生成源码 带后台
  7. 二进制转8421bcd码_中山CVI转CVBS芯视音科技原装
  8. Fuel 9.0安装的Openstack Controller节点进程整理
  9. openwrt顶层Makefile分析-转
  10. 我的世界java1.15.2光影_我的世界1.15.2简单forge服务器搭建笔记
  11. 自定义 C++ 中的 range() 函数
  12. 集合框架和泛型练习题(含代码)
  13. SPSS统计分析行业应用实战--SPSS 23.0新增
  14. 51单片机教室人数进出统计检测LCD1602管显示装置红外传感器
  15. word中-文字尾部空格自动添加下划线的步骤
  16. 2022推荐大宗商品行业研究报告投资策略产业发展前景市场行情分析(附件中为网盘链接,报告持续更新)
  17. 系统托盘安全删除硬件图标不见了(任务栏USB图标不见了)的故障处理图文详解
  18. ubuntu系统下THETA S 全景相机 通过ROS导出图像
  19. php 星盘代码,爱星盘SDK开发接口说明
  20. 微软azure服务器配置,配置持续部署 - Azure App Service | Microsoft Docs

热门文章

  1. FreeRTOS知识点
  2. HDU1716(全排列)
  3. python中统计列表各个元素的个数
  4. IT界程序员几大恶习能立即让你变穷,你有吗?
  5. github--新手使用错误分析
  6. LINUX下安装ORACLE,完全搞定
  7. 维护一套同时兼容 iOS 6 和 iOS 7,并且能够自动适应两个系统的 UI 风格的代码...
  8. 用固定收敛标准特征迭代次数法实现分类是不是一个巧合?
  9. CV书单-Benjio PAMI review (up tp 2013)
  10. 3.3 集束搜索-深度学习第五课《序列模型》-Stanford吴恩达教授