Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes
生活随笔
收集整理的這篇文章主要介紹了
Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
BZOJ2200
聽(tīng)說(shuō)加上slf優(yōu)化的spfa的卡過(guò),真的不想寫(xiě)這些東西。
考慮使用堆優(yōu)化的dij算法。
先加上所有雙向邊,然后dfs一下搜出所有由雙向邊構(gòu)成的聯(lián)通塊,然后加上所有的單向邊,一邊對(duì)所有聯(lián)通塊拓?fù)渑判蛞贿呍诼?lián)通塊內(nèi)部處理最短路,因?yàn)樗械碾p向邊都是不帶負(fù)權(quán)的,而單向邊都是有負(fù)權(quán)的,所以這樣規(guī)避dij貪心的錯(cuò)誤之處。
注意到一個(gè)$inf$可能被另一個(gè)$inf$加上一個(gè)負(fù)權(quán)邊拓展得到,所以最后的答案可能會(huì)小于$inf$,檢驗(yàn)的時(shí)候注意取的極大值要小于一開(kāi)始賦的$inf$。
時(shí)間復(fù)雜度$O(nlogn)$。
Code:
#include <cstdio> #include <cstring> #include <queue> #include <iostream> #include <vector> using namespace std; typedef pair <int, int> pin;const int N = 25005; const int M = 2e5 + 5; const int inf = 1e8;int n, m1, m2, st, tot = 0, head[N], dis[N]; int l = 1, r = 0, q[N], deg[N], sccCnt = 0, 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 = 0; char ch = 0; T op = 1;for(; ch > '9'|| ch < '0'; ch = getchar())if(ch == '-') op = -1;for(; ch >= '0' && ch <= '9'; ch = getchar())X = (X << 3) + (X << 1) + ch - 48;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 = 0; 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] = 1;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 = 1; i <= m1; i++) {read(x), read(y), read(v);add(x, y, v), add(y, x, v);}for(int i = 1; i <= n; i++)if(!bel[i]) ++sccCnt, dfs(i);for(int x, y, v, i = 1; i <= m2; i++) {read(x), read(y), read(v);add(x, y, v);deg[bel[y]]++;}for(int i = 1; i <= sccCnt; i++)if(!deg[i]) q[++r] = i;memset(dis, 0x3f, sizeof(dis)); dis[st] = 0;for(; l <= r; ++l) dij(q[l]);for(int i = 1; i <= n; i++) {if(dis[i] > inf) puts("NO PATH");else printf("%d\n", dis[i]);}return 0; } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/CzxingcHen/p/9562972.html
總結(jié)
以上是生活随笔為你收集整理的Luogu 3008 [USACO11JAN]道路和飞机Roads and Planes的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: .net core mysql Code
- 下一篇: Sql Server 连接池