农夫约翰正在一个新的销售区域对他的牛奶销售方案进行调查。

他想把牛奶送到 T 个城镇,编号为 1∼T。

这些城镇之间通过 R 条道路 (编号为 1 到 R) 和 P 条航线 (编号为 1 到 P) 连接。

每条道路 i 或者航线 i 连接城镇 Ai 到 Bi,花费为 Ci。

对于道路,0≤Ci≤10,000;然而航线的花费很神奇,花费 Ci 可能是负数(−10,000≤Ci≤10,000)。

道路是双向的,可以从 Ai 到 Bi,也可以从 Bi 到 Ai,花费都是 Ci。

然而航线与之不同,只可以从 Ai 到 Bi。

事实上,由于最近恐怖主义太嚣张,为了社会和谐,出台了一些政策:保证如果有一条航线可以从 Ai 到 Bi,那么保证不可能通过一些道路和航线从 Bi 回到 Ai。

由于约翰的奶牛世界公认十分给力,他需要运送奶牛到每一个城镇。

他想找到从发送中心城镇 S 把奶牛送到每个城镇的最便宜的方案。

输入格式

第一行包含四个整数 T,R,P,S。

接下来 R 行,每行包含三个整数(表示一个道路)Ai,Bi,Ci。

接下来 P 行,每行包含三个整数(表示一条航线)Ai,Bi,Ci。

输出格式

第 1…T 行:第 i 行输出从 S 到达城镇 i 的最小花费,如果不存在,则输出 NO PATH。

数据范围

1≤T≤25000,
1≤R,P≤50000,
1≤Ai,Bi,S≤T

输入样例:

6 3 3 4
1 2 5
3 4 5
5 6 10
3 5 -100
4 6 -100
1 3 -10

输出样例:

NO PATH
NO PATH
5
0
-95
-100

思路:

/*
这题如果直接用spfa来做的话,因为spfa已经死了,所以会被卡成 O(nm) TLE。而因为有负权边的原因,不能直接用 dij 来做。这里我们可以发现题目利用恐怖分子之名为我们提供了一个很有用的条件:单向边没有回路。如果通过一条单向边从 a 走到 b ,那么必不可能通过另外一条单向边从 b 走到 a 。因此这里我们可以把单向边连起来的每一块看成是一个连通块。因为联通块内部是没有负权边的,因此在联通块内部可以使用 dij 来求得最短路。而在联通块之间虽然有负权边,但这些负权边组成了一个 DAG (有向无环图)。因此我们可以通过求拓扑序列的方式来求得其最短路。时间复杂度是 O(n)。这样我们就能把总体的时间复杂度控制在 O(nlogm) 了。1、先输入所有双向道路,然后dfs出所有连通块,计算两个数组:id[]存储每个点属于哪个连通块;vector<int>block[]存储每个连通块里有哪些点
2、输入所有航线,同时统计出每个连通块的入度
3、按照拓扑序,依次处理每个连通块,先将所有入度为0的连通块的编号加入队列中。
4、每次从队头取出一个连通块的编号。
5、将block[bid]中的所有点加入堆中,然后对堆中所有点做dijkstra。
6、每次取出堆中的距离最小的点ver。
7、然后遍历ver的所有邻点j,如果id[ver] == id[j],如果j能被更新,则将j插入堆中;否则说明访问到一条航线,则将id[j]这个连通块的入度减一,如果减到0了,就将其插入到拓扑序的队列中
*/

代码:

#include <bits/stdc++.h>
#define x first;
#define y second;
using namespace std;
typedef pair<int, int> PII;
const int N = 25010, M = 150010, INF = 0x3f3f3f3f;
int n, mr, mp, S;
int id[N];
int h[N], ne[M], e[M], w[M], idx;
int dist[N], din[N];
vector<int> block[N];
int bcnt;
queue<int> qu;
int st[N];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, block[bid].push_back(u);for (int i = h[u]; i != -1; i = ne[i]){int j = e[i];if (!id[j])dfs(j, bid);}
}void dijkstra(int bid)
{priority_queue<PII, vector<PII>, greater<PII>> heap;for (auto it : block[bid]) // 全都要放入 不知道哪个最小heap.push({dist[it], it});while (heap.size()){PII t = heap.top();heap.pop();int ver = t.y;if (st[ver])continue;st[ver] = 1;for (int i = h[ver]; i != -1; i = ne[i]){int j = e[i];if (id[j] != id[ver] && --din[id[j]] == 0)qu.push(id[j]);if (dist[j] > dist[ver] + w[i]){dist[j] = dist[ver] + w[i]; // 负权边也更新if (id[j] == id[ver])heap.push({dist[j], j});}}}
}void topsort()
{memset(dist, 0x3f, sizeof(dist));dist[S] = 0;for (int i = 1; i <= bcnt; i++){if (!din[i])qu.push(i);}while (qu.size()){int t = qu.front();qu.pop();dijkstra(t);}
}int main()
{cin >> n >> mr >> mp >> S;memset(h, -1, sizeof(h));while (mr--){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);}for (int i = 1; i <= n; i++){if (!id[i]){bcnt++;dfs(i, bcnt);}}while (mp--){int a, b, c;cin >> a >> b >> c;din[id[b]]++;add(a, b, c);}topsort();/*对于这题来说,假设起点在第三个连通块里,第一个连通块到第二个连通块有一条负权的航线,那么第二个连通块中的dist会被更新为dist[i] < INF。根据题意不存在环,因此第一个和第二个连通块中的城镇都是不可达的*/for (int i = 1; i <= n; i++)if (dist[i] > INF / 2)cout << "NO PATH" << endl;elsecout << dist[i] << endl;return 0;
}

342. 道路与航线相关推荐

  1. AcWing 342. 道路与航线 (双端队列广搜问题,SPFA)

    题目描述 农夫约翰正在一个新的销售区域对他的牛奶销售方案进行调查. 他想把牛奶送到T个城镇,编号为1~T. 这些城镇之间通过R条道路 (编号为1到R) 和P条航线 (编号为1到P) 连接. 每条道路i ...

  2. AcWing 342. 道路与航线 (连通块Dijkstra+拓扑序||spfa+slf优化)

    整理的算法模板:ACM算法模板总结(分类详细版) 农夫约翰正在一个新的销售区域对他的牛奶销售方案进行调查. 他想把牛奶送到T个城镇,编号为1~T. 这些城镇之间通过R条道路 (编号为1到R) 和P条航 ...

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

    题目分析 来源:acwing 分析: 道路:双向,边权非负, 航线:单向,边权可正可负,且无环. 根据题意,点可以分为很多团(连通块),团内部只有道路(道路是双向的,而且是连通的,所以不能存在航线,否 ...

  4. [BZOJ 2200][Usaco2011 Jan]道路和航线 spfa+SLF优化

    Description Farmer John正在一个新的销售区域对他的牛奶销售方案进行调查.他想把牛奶送到T个城镇 (1 <= T <= 25,000),编号为1T.这些城镇之间通过R条 ...

  5. 「BZOJ2200」[Usaco2011 Jan] 道路和航线 - 最短路+拓扑排序

    ->点我进原题 [Usaco2011 Jan]道路和航线 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1116 Solved: 410 Des ...

  6. 道路与航线(spfa+deque优化)

    农夫约翰正在一个新的销售区域对他的牛奶销售方案进行调查. 他想把牛奶送到T个城镇,编号为1~T. 这些城镇之间通过R条道路 (编号为1到R) 和P条航线 (编号为1到P) 连接. 每条道路 i 或者航 ...

  7. 【图论专题】单源最短路的综合应用

    单源最短路径经常与DFS.DP.二分.拓扑排序等算法的结合使用. 题目列表: 题目 算法 AcWing 1135. 新年好 最短路+DFS AcWing 340. 通信线路 二分+双端队列BFS Ac ...

  8. 0x61.图论 - 最短路

    目录 单源最短路径 一.Dijkstra算法 1.常用的优先队列优化 2.更优的线段树优化 3.最强的zkw线段树优化 二.SPFA算法 三.分层图最短路 1.(二维分层图)AcWing 340. 通 ...

  9. 第三章 图论【未完成】

    目录 单源最短路的建图方式 1129. 热浪[最普通的最短路板子] 1128. 信使[基本的最短路 + 稍微的扩展] 1127. 香甜的黄油[稍微变种的最短路] 1126. 最小花费[Dijkstra ...

最新文章

  1. vs2010 学习Silverlight学习笔记(7):控件样式与模板
  2. ftp java listfiles_Java FTPClient.listFiles()不能获取目录里的文件
  3. Dubbo简介与基本概念
  4. 三值的排序 Sorting a Three-Valued Sequence
  5. java esp_在我的ESP游戏方法中非法开始表达
  6. Mozilla开发全新的公开网络API WebXR 来实现增强现实
  7. 微信小程序 三元运算 checked
  8. redis 内存溢出_查漏补缺,Redis为什么会这么快,看完这七点你就知道了
  9. mysql utf-8长度_MySQL VARCHAR长度和UTF-8?mysql
  10. Markdown写作入门
  11. 显示浏览器表单输入框的缓存密码
  12. 招投标系统简介 招投标系统源码 java招投标系统 spring cloud spring boot 招投标系统功能设计
  13. 小米4c android5.1,小米4c原版官方刷机包安卓5.1.1rom线刷包
  14. 利用Global Mapper处理正摄卫片
  15. 实战|淘宝用户行为分析案例
  16. 再谈自适应学习——技术篇
  17. PWM控制直流电机(单片机实验)
  18. 绘图和可视化(Python)
  19. 【IDEA】idea插件的安装和删除
  20. 正确的Python学习路线图,来了!

热门文章

  1. J8583CN解析ISO8583协议报文注意点
  2. CDR插件开发之Addon插件007 - Addon插件简介和案例演示
  3. 带你学习如何更好的使用uni-app(一)
  4. 音频录制(react)
  5. 链塔智库|区块链产业要闻及动态周报(2021年8月第3周)
  6. 小魔推如何解决实体商家痛点,实现短视频高转化
  7. 快手火山抖音视频(包含其他视频)跨平台操作搬运,下载,消重,全自动操作解放双手...
  8. C语言:*(p++)与*p++ *(++p)与*++p ++*p与++(*p) (*p)++的区别
  9. 江苏省普通话水平测试计算机评分细则,江苏省计算机辅助普通话水平测试评分细则...
  10. SpringBoot word文件转pdf