物語_Kruskal
阿新 • • 發佈:2017-12-22
相同 post mono 大致 ret nbsp open 特意 getch
題目描述
某一天,少年邂逅了同病相連的IA。見面後,IA一把牽起少年的手,決定和他一起逃離部落,離開這個無法容身的是非之地。
要逃離部落,少年和IA就需要先選擇一條耗時最少的路線,從而避免被部落的大人們抓到。部落可以大致分為N個區域,少年和IA在區域1,部落的出口設在區域N。此外部落還有M條連接兩個區域道路。道路是無向的,沒有一條道路的兩端連接相同的區域,也沒有兩條道路所連接的兩個區域完全相同。對於其中前(M?1)條道路,其通過時間是確定的,但最後一條道路,由於地理因素,通過其的時間會不斷變化。
現在,少年和IA得知了在K個不同的時段裏,通過第M條道路的時間,請您分別計算出在這K 個時段中逃離部落的最少時間,以幫助他們確定行動的時刻。
思路
對於每一條不確定的路徑(a,b),我們可以不經過它,可以從a進去,也可以從b進去
那麽我們就可以用頭尾跑兩遍Kruskal就可以知道到這兩個點的最短距離
然後判斷出解即可
特意放出數據規模,我們可以看到有點的數據是構造出來卡spfa的,所以
Kruskal!!!!
#include <stdio.h> #include <cstring> #include <string> #include <queue> using namespace std; #define N 200505 #define M 1000005 #definefill(x, y) memset(x, y, sizeof(x)) #define LL long long #define min(x, y) ((x) < (y) ? (x) : (y)) const LL INF = 1e+18; LL state[N], state1[N]; int ls[M], n, m, k, st, ed; bool exits[N]; struct edge { int to, w, next; }e[M]; int l = 0; struct cmp { int operator()(int a, int b) {return state[a] > state[b]; } }; struct cmp1 { int operator()(int a, int b) { return state1[a] > state1[b]; } }; int add(int x, int y, int w) { e[++l] = (edge){y, w, ls[x]}; ls[x] = l; } inline int read() { int x = 0, p = 1; char ch = getchar(); while (ch < ‘0‘ || ch > ‘9‘) {if (ch == ‘-‘) p = -1; ch = getchar();} while (ch >= ‘0‘ && ch <= ‘9‘) {x = (x << 1) + (x << 3) + ch - ‘0‘; ch = getchar();} return x * p; } void write(LL x) { if (x < 10) { putchar(x + ‘0‘); return; } else { write(x / 10); write(x % 10); } } int spfa() { priority_queue<int, vector<int>, cmp > t; for (int i = 1; i <= n; i++) state[i] = INF; exits[1] = 1; t.push(1); state[1] = 0; while (!t.empty()) { int now = t.top(); t.pop(); for (int i = ls[now]; i; i = e[i].next) { if (state[e[i].to] > state[now] + e[i].w) { state[e[i].to] = state[now] + e[i].w; if (!exits[e[i].to]) { exits[e[i].to] = 1; t.push(e[i].to); } } } exits[now] = 0; } } int spfa1() { priority_queue<int, vector<int>, cmp1 > t; for (int i = 1; i <= n; i++) state1[i] = INF; exits[n] = 2; t.push(n); state1[n] = 0; while (!t.empty()) { int now = t.top(); t.pop(); for (int i = ls[now]; i; i = e[i].next) { if (state1[e[i].to] > state1[now] + e[i].w) { state1[e[i].to] = state1[now] + e[i].w; if (exits[e[i].to] != 2) { exits[e[i].to] = 2; t.push(e[i].to); } } } exits[now] = 0; } } int main() { freopen("monogatari.in", "r", stdin); freopen("monogatari.out", "w", stdout); n = read(); m = read(); k = read(); for (int i = 1; i < m; i++) { int x = read(), y = read(), w = read(); add(x, y, w); add(y, x, w); } st = read(); ed = read(); spfa(); spfa1(); for (int i = 1; i <= k; i++) { int x = read(); LL mi = state[n]; mi = min(state[st] + state1[ed] + x, mi); mi = min(state[ed] + state1[st] + x, mi); if (mi < INF) { write(mi); putchar(‘\n‘); } else { printf("+Inf\n"); } } }
物語_Kruskal