ACwing342. 道路与航线
这道题是把拓扑排序和迪杰斯特拉交叉进行。
#include <iostream> #include <stdio.h> #include <algorithm> #include <cstring> #include <queue> #include <vector> using namespace std; typedef pair<int, int> PII; const int N = 25005, M = 50005, inf = 1e9; int h[N], e[M * 3], w[M * 3], ne[M * 3], cnt, id[N], idnow; int n, r, p, s; bool flag[N], vis[N]; int dist[N], in_degree[N]; vector<int> vec[N]; queue<int> q_block; inline void add(int a, int b, int c) { e[++cnt] = b; w[cnt] = c; ne[cnt] = h[a]; h[a] = cnt; } void dfs(int u,int mark_id) { vec[mark_id].push_back(u); id[u] = mark_id; for(int i = h[u]; i; i = ne[i]) { int j = e[i]; if(!flag[j]) { flag[j] = 1; dfs(j, mark_id); } } } void DJ(int u) { priority_queue<PII, vector<PII>, greater<PII>> Q; for(auto i : vec[u]) Q.push({dist[i], i}); while(!Q.empty()) { PII q_top = Q.top(); Q.pop(); int x = q_top.second; if(vis[x]) continue; vis[x] = 1; for(int i = h[x]; i; i = ne[i]) { int j = e[i]; if(id[j] == id[x]) { if(dist[j] > dist[x] + w[i]) { dist[j] = dist[x] + w[i]; Q.push({dist[j], j}); } } else { dist[j] = min(dist[j], dist[x] + w[i]); in_degree[id[j]]--; if(!in_degree[id[j]]) { q_block.push(id[j]); } } } } } void func() { memset(dist, 0x3f, sizeof(dist)); dist[s] = 0; for(int i = 1; i <= idnow; i++) { if(!in_degree[i]) { q_block.push(i); } } while(!q_block.empty()) { int block_first = q_block.front(); q_block.pop(); DJ(block_first); } } int main() { scanf("%d%d%d%d", &n, &r, &p, &s); for(int i = 1; i <= r; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); add(b, a, c); } for(int i = 1; i <= n; i++) if(!flag[i]) { flag[i] = 1; idnow++; dfs(i, idnow); } for(int i = 1; i <= p; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); in_degree[id[b]]++; } func(); for(int i = 1; i <= n; i++) if(dist[i] < inf) printf("%d\n", dist[i]); else puts("NO PATH"); system("pause"); return 0; }
为了方便处理,省去各种各样的特判(同时保持拓扑排序的正确性),我们在进入到一个新连通块时,在进行迪杰斯特拉之前,直接把这个连通块内的所有点统一加入优先队列。
本文作者:smartljy
本文链接:https://www.cnblogs.com/smartljy/p/17875513.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步