BZOJ2200

听说加上slf优化的spfa的卡过,真的不想写这些东西。

考虑使用堆优化的dij算法。

先加上所有双向边,然后dfs一下搜出所有由双向边构成的联通块,然后加上所有的单向边,一边对所有联通块拓扑排序一边在联通块内部处理最短路,因为所有的双向边都是不带负权的,而单向边都是有负权的,所以这样规避dij贪心的错误之处。

注意到一个$inf$可能被另一个$inf$加上一个负权边拓展得到,所以最后的答案可能会小于$inf$,检验的时候注意取的极大值要小于一开始赋的$inf$。

时间复杂度$O(nlogn)$。

Code:

#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <vector>
using namespace std;
typedef pair <int, int> pin; const int N = ;
const int M = 2e5 + ;
const int inf = 1e8; int n, m1, m2, st, tot = , head[N], dis[N];
int l = , r = , q[N], deg[N], sccCnt = , bel[N];
bool vis[N];
vector <int> scc[N]; struct Edge {
int to, nxt, val;
} e[M]; inline void add(int from, int to, int val) {
e[++tot].to = to;
e[tot].val = val;
e[tot].nxt = head[from];
head[from] = tot;
} template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} void dfs(int x) {
bel[x] = sccCnt, scc[sccCnt].push_back(x);
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(!bel[y]) dfs(y);
}
} priority_queue <pin> Q;
void dij(int c) {
for(unsigned int i = ; i < scc[c].size(); i++) Q.push(pin(-dis[scc[c][i]], scc[c][i]));
for(; !Q.empty(); ) {
int x = Q.top().second; Q.pop();
if(vis[x]) continue;
vis[x] = ;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(bel[y] == c) {
if(dis[y] > dis[x] + e[i].val) {
dis[y] = dis[x] + e[i].val;
Q.push(pin(-dis[y], y));
}
} else {
if(dis[y] > dis[x] + e[i].val) dis[y] = dis[x] + e[i].val;
deg[bel[y]]--;
if(!deg[bel[y]]) q[++r] = bel[y];
}
}
}
} int main() {
read(n), read(m1), read(m2), read(st);
for(int x, y, v, i = ; i <= m1; i++) {
read(x), read(y), read(v);
add(x, y, v), add(y, x, v);
} for(int i = ; i <= n; i++)
if(!bel[i]) ++sccCnt, dfs(i); for(int x, y, v, i = ; i <= m2; i++) {
read(x), read(y), read(v);
add(x, y, v);
deg[bel[y]]++;
} for(int i = ; i <= sccCnt; i++)
if(!deg[i]) q[++r] = i; memset(dis, 0x3f, sizeof(dis)); dis[st] = ;
for(; l <= r; ++l) dij(q[l]); for(int i = ; i <= n; i++) {
if(dis[i] > inf) puts("NO PATH");
else printf("%d\n", dis[i]);
} return ;
}

Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes的更多相关文章

  1. P3008 [USACO11JAN]道路和飞机Roads and Planes

    P3008 [USACO11JAN]道路和飞机Roads and Planes Dijkstra+Tarjan 因为题目有特殊限制所以不用担心负权的问题 但是朴素的Dijkstra就算用堆优化,也显然 ...

  2. bzoj1626 / P2872 [USACO07DEC]道路建设Building Roads

    P2872 [USACO07DEC]道路建设Building Roads kruskal求最小生成树. #include<iostream> #include<cstdio> ...

  3. luogu 2296 寻找道路 (搜索)

    luogu 2296 寻找道路 题目链接:https://www.luogu.org/problemnew/show/P2296 从终点bfs或者dfs,找出所有终点能到达的点. 然后再从1到n看一下 ...

  4. 洛谷——P2872 [USACO07DEC]道路建设Building Roads

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  5. 洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  6. Luogu 2296 寻找道路

    https://www.luogu.org/problemnew/show/2296 题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以 ...

  7. USACO 07DEC 道路建设(Building Roads)

    Farmer John had just acquired several new farms! He wants to connect the farms with roads so that he ...

  8. Luogu P3007 [USACO11JAN]大陆议会The Continental Cowngress

    P3007 [USACO11JAN]大陆议会The Continental Cowngress 题意 题意翻译 简述:给出\(n\)个法案,\(m\)头牛的意见,每头牛有两个表决格式为"支持 ...

  9. 【luogu P2296 寻找道路】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2296 题意:给定起点终点,找一条从起点到终点的最短路径使路上的每个点都能有路径到达终点. 我们先反着建一遍图 ...

随机推荐

  1. New Concept English there (60)

    33w/m 43 Punctuality is a necessary habit in all public affairs in civilized society. Without it, no ...

  2. Codeforces Round #271 (Div. 2)D(递推,前缀和)

    很简单的递推题.d[n]=d[n-1]+d[n-k] 注意每次输入a和b时,如果每次都累加,就做了很多重复性工作,会超时. 所以用预处理前缀和来解决重复累加问题. 最后一个细节坑了我多次: print ...

  3. 未定义的标示符“RECT”,引入了windows.h头文件也没有用?

    我用的是win8的vs2012,RECT应该引入什么头文件?windows.h我第一个就引入了,去windows.h里面搜也搜不到RECT这个关键字,应该引入哪个头文件呢? 真是奇怪啊,是不是还需要什 ...

  4. BZOJ - 1036 树的统计Count (树链剖分+线段树)

    题目链接 #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3f3f3f; ],mx[ ...

  5. python发短信功能

    http://www.cnblogs.com/martianShu/p/5847289.html

  6. AMD 规范

    AMD(异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件. AMD 定义了一套 JavaScript 模块依赖异步加载标准 ...

  7. 获取url参数并且中文不乱码的方法

    function getUrlArgument(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...

  8. 图片的base64编码通过javascript生成图片--当前URL地址的二维码应用

    前面的话 在电脑端发现一篇好的博文,想在手机上访问.这时,就必须打开手机浏览器输入长长的URL地址才行,非常不方便.如果在博客标题的后面跟一张小的图片,点击该图片后,出现一张二维码的大图,然后再通过手 ...

  9. Python修复图像文件后缀名

    网上爬了很多图片,有很多错误. 有的不是图片文件,需要删除 有的后缀名错误,需要更正 用的的python脚本 #!/usr/bin/env python #-*- coding: utf-8 -*-# ...

  10. BZOJ2648:SJY摆棋子

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...