1. 程式人生 > >常州模擬賽d5t1 journalist

常州模擬賽d5t1 journalist

es2017 字典序 color sin push 計數 long memset span

技術分享

技術分享

分析:出題人喪心病狂卡spfa......只能用dijkstar+堆優化.

主要的難點是字典序的處理上,一個想法是在做最短路的時候處理,邊松弛邊記錄,比個大小記錄最佳答案.具體的思路大概和最短路計數差不多,當遇到d[u] + w[i] == d[v]是,說明到d[v]有兩條最短路了,更新一下答案。

但是這樣效率太低了,每一次松弛都要更新一次,能不能一次性更新完呢?可以的.我們在跑完最短路後把滿足d[u] + w[i] == d[v]的點v加入u的鄰接表中,排個序,然後dfs一遍就好了.

#include <cstdio>
#include <cstring>
#include 
<iostream> #include <algorithm> #include <string> #include <cmath> #include <queue> #include <vector> using namespace std; const long long inf = 1e15; struct node { long long len; int x; }; bool operator < (node a, node b) { return a.len > b.len; }
int n, m,b[200010],head[200010],to[400010],nextt[400010],tot = 1,w[400010],vis[200010]; int u[400010], v[400010], z[400010],ans[200010]; long long d[200010]; vector <int> a[200010]; void add(int x, int y, int z) { w[tot] = z; to[tot] = y; nextt[tot] = head[x]; head[x] = tot++; } void dijkstar() { d[1] = 0; priority_queue
<node> q; node t; t.len = 0; t.x = 1; q.push(t); while (!q.empty()) { while (!q.empty() && vis[q.top().x]) q.pop(); if (q.empty()) break; node u = q.top(); q.pop(); long long len = u.len; int x = u.x; vis[x] = 1; for (int i = head[x]; i;i = nextt[i]) { int v = to[i]; if (len + w[i] < d[v]) { d[v] = len + w[i]; node temp; temp.len = d[v]; temp.x = v; q.push(temp); } } } } bool cmp(int x, int y) { return b[x] < b[y]; } void dfs(int depth, int x) { if (vis[x]) return; vis[x] = 1; ans[depth] = x; if (x == n) { for (int i = 1; i <= depth; i++) printf("%d ", b[ans[i]]); printf("\n"); return; } for (int i = 0; i < a[x].size(); i++) dfs(depth + 1, a[x][i]); } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &b[i]); for (int i = 1; i <= m; i++) { scanf("%d%d%d", &u[i], &v[i], &z[i]); add(u[i], v[i], z[i]); } for (int i = 1; i <= n; i++) d[i] = inf; dijkstar(); printf("%lld\n", d[n]); for (int i = 1; i <= m; i++) if (d[u[i]] + z[i] == d[v[i]]) a[u[i]].push_back(v[i]); for (int i = 1; i <= n; i++) sort(a[i].begin(), a[i].end(), cmp); memset(vis, 0, sizeof(vis)); dfs(1, 1); return 0; }

常州模擬賽d5t1 journalist