題目TP門優化
很明顯是一個最短路,可是如何建圖纔是關鍵。ui
對於每個不可遍歷到的點,能夠向外擴散,找到危險城市。spa
如果對於每個這樣的城市進行搜索,時間複雜度就爲\(O(n^2)\),顯然過不了。不妨把它們放在一個BFS裏面進行搜索,先遍歷能夠向外延伸最長的點,由於這個點是能夠存活很長的。若以後再遍歷到這個點的時候,就不用在遍歷了,由於這時候的存活時間已經沒有以前遍歷的時候高了。BFS+打標記遍歷完一張圖只須要\(O(n)\)的時間複雜度,很大程度上優化了建圖方面。code
最後根據所給的邊跑一遍最短路便可,代碼以下:get
#include <queue> #include <cstdio> #include <vector> #include <cstring> using namespace std; #define LL long long #define INF 0x3f3f3f3f void Quick_Read(LL &N) { N = 0; char c = getchar(); LL op = 1; while(c < '0' || c > '9') { if(c == '-') op = -1; c = getchar(); } while(c >= '0' && c <= '9') { N = (N << 1) + (N << 3) + c - 48; c = getchar(); } N *= op; } const LL MAXN = 1e6 + 5; struct Node { LL to, dist; Node() {} Node(LL T, LL D) { to = T; dist = D; } friend bool operator > (Node x, Node y) { return x.dist > y.dist; } }; struct Flee { LL step, id; Flee() {} Flee(LL I, LL S) { step = S; id = I; } friend bool operator > (Flee x, Flee y) { return x.step < y.step; } }; vector<LL> v[MAXN]; vector<Node> wg[MAXN]; queue<Flee> que; priority_queue<Node, vector<Node>, greater<Node> > qu; bool f[MAXN], vis[MAXN], vi[MAXN], V[MAXN]; LL c[MAXN], w[MAXN]; LL A[MAXN], B[MAXN], d[MAXN]; LL n, m, k, s, p, q; void Dijkstra() { memset(d, 0x3f, sizeof(d)); qu.push(Node(1, 0)); d[1] = 0; while(!qu.empty()) { LL now = qu.top().to; qu.pop(); if(V[now]) continue; V[now] = true; LL SIZ = wg[now].size(); for(LL i = 0; i < SIZ; i++) { LL next = wg[now][i].to; if(d[now] + wg[now][i].dist < d[next]) { d[next] = d[now] + wg[now][i].dist; qu.push(Node(next, d[next])); } } } printf("%lld", d[n]); } void bfs() { for(LL i = 1; i <= k; i++) { que.push(Flee(c[i], s)); vi[c[i]] = 1; } while(!que.empty()) { Flee now = que.front(); que.pop(); if(vis[now.id]) continue; vis[now.id] = 1; vi[now.id] = 1; if(now.step == 0) continue; LL SIZ = v[now.id].size(); for(LL i = 0; i < SIZ; i++) { LL nex = v[now.id][i]; que.push(Flee(nex, now.step - 1)); } } } void Read() { Quick_Read(n); Quick_Read(m); Quick_Read(k); Quick_Read(s); Quick_Read(p); Quick_Read(q); for(LL i = 1; i <= k; i++) { Quick_Read(c[i]); f[c[i]] = true; } for(LL i = 1; i <= m; i++) { Quick_Read(A[i]); Quick_Read(B[i]); v[A[i]].push_back(B[i]); v[B[i]].push_back(A[i]); } } void Build() { for(LL i = 1; i <= n; i++) w[i] = p; for(LL i = 1; i <= n; i++) if(vi[i]) w[i] = q; for(LL i = 1; i <= k; i++) w[c[i]] = INF; for(LL i = 1; i <= m; i++) { if(B[i] == n) { wg[A[i]].push_back(Node(B[i], 0)); wg[B[i]].push_back(Node(A[i], w[A[i]])); } else if(A[i] == n) { wg[A[i]].push_back(Node(B[i], w[B[i]])); wg[B[i]].push_back(Node(A[i], 0)); } else { wg[A[i]].push_back(Node(B[i], w[B[i]])); wg[B[i]].push_back(Node(A[i], w[A[i]])); } } } int main() { Read(); bfs(); Build(); Dijkstra(); return 0; }