1. 程式人生 > >物語_Kruskal

物語_Kruskal

相同 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
#define
fill(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