BZOJ2763: [JLOI2011]飛行路線(分層圖 最短路)
阿新 • • 發佈:2018-11-09
題意
Sol
分層圖+最短路
建\(k+1\)層圖,對於邊\((u, v, w)\),首先在本層內連邊權為\(w\)的無向邊,再各向下一層對應的節點連邊權為\(0\)的有向邊
如果是取最大最小值的話可以考慮二分答案+最短路
// luogu-judger-enable-o2 // luogu-judger-enable-o2 #include<bits/stdc++.h> #define Pair pair<int, int> #define MP make_pair #define fi first #define se second using namespace std; const int MAXN = 2e5 + 10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, K, S, T, TT, vis[MAXN], dis[MAXN]; vector<Pair> v[MAXN]; void AddEdge(int x, int y, int z, int f) { v[x].push_back(MP(y, z)); if(f) v[y].push_back(MP(x, z)); } void Dij(int s) { priority_queue<Pair> q; q.push(MP(0, s)); memset(dis, 0x3f, sizeof(dis)); dis[s] = 0; while(!q.empty()) { if(vis[q.top().se]) {q.pop(); continue;} int p = q.top().se; q.pop(); vis[p] = 1; for(int i = 0; i < v[p].size(); i++) { int to = v[p][i].fi, w = v[p][i].se; if(dis[to] > dis[p] + w) dis[to] = dis[p] + w, q.push(MP(-dis[to], to)); } } } int main() { // freopen("a.in", "r", stdin); N = read(); M = read(); K = read(); S = read() + 1; T = read() + 1; TT = N * (K + 1) + 1; for(int i = 1; i <= M; i++) { int u = read() + 1, v = read() + 1, w = read(); for(int j = 0; j < K; j++) { AddEdge(j * N + u, j * N + v, w, 1); AddEdge(j * N + u, (j + 1) * N + v, 0, 0); AddEdge(j * N + v, (j + 1) * N + u, 0, 0); } AddEdge(N * K + u, N * K + v, w, 1); } for(int j = 0; j <= K; j++) AddEdge(j * N + T, TT, 0, 0); Dij(S); printf("%d", dis[TT]); return 0; }