1. 程式人生 > >CodeForces 715B Complete The Graph 特殊的dijkstra

CodeForces 715B Complete The Graph 特殊的dijkstra

檢查 bool 如果 min 範圍 show 題解 sign pri

Complete The Graph

題解:

比較特殊的dij的題目。

dis[x][y] 代表的是用了x條特殊邊, y點的距離是多少。

然後我們通過dij更新dis數組。

然後在跑的時候,把特殊邊都先當做1在跑,並且經過特殊邊的時候,記得將x更新。

然後如果dis[0][t] < L 則代表不用特殊邊也會小於L。所以無論是特殊的邊答案是多少,dis[0][t]<L也是固定的。

然後我們不斷檢查dis[c][t] (for c 1 to N) 是不是 <= L 。

找到對應的dis[c][t]之後, 把最短路上的特殊邊更新成符合答案的值。 其他特殊邊更新成L+1。

代碼從學長那裏學的, 可以說十分像了。

對我來說比較新穎的是, 把邊初始值賦值為L+1,這樣就可以在int的範圍內跑完全程的dij了, 畢竟如果路徑長度 > L 之後就沒必要再跑了。

代碼:

技術分享圖片
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define
se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int
_inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e3 + 10; const int M = 2e4 + 100; int n, m, L, s, t; int head[N], to[M], val[M], nt[M], tot; void add(int u, int v, int w){ to[tot] = v; val[tot] = w; nt[tot] = head[u]; head[u] = tot++; } int dis[N][N]; pll pre[N][N]; typedef tuple<int,int,int> tup; priority_queue<tup, vector<tup>, greater<tup> > pq; bool dij(){ for(int i = 0; i < N; ++i) fill(dis[i], dis[i] + N, L+1); dis[0][s] = 0; pq.push(tup(0,0,s)); /// dis , 0-edge, now-point while(!pq.empty()){ int dd, c, u; tie(dd, c, u) = pq.top(); pq.pop(); if(dd != dis[c][u]) continue; for(int i = head[u]; ~i; i = nt[i]){ int v = to[i]; int w = dd + val[i] + (!val[i]); int nc = c + (!val[i]); if(nc >= N) continue; if(dis[nc][v] > w){ dis[nc][v] = w; pq.push(tup(w, nc, v)); pre[nc][v] = pll(u, i); } } } if(dis[0][t] < L) return false; if(dis[0][t] == L) return true; for(int c = 1; c < N; ++c){ if(dis[c][t] <= L){ int add = L - dis[c][t]; int cc = c, now = t; while(now != s){ pll tt = pre[cc][now]; now = tt.fi; if(val[tt.se] == 0){ val[tt.se] = val[tt.se^1] = add + 1; add = 0; cc--; } } return true; } } return false; } int main(){ memset(head, -1, sizeof head); scanf("%d%d%d%d%d", &n, &m, &L, &s, &t); int u, v, w; for(int i = 1; i <= m; ++i){ scanf("%d%d%d", &u, &v, &w); add(u, v, w); add(v, u, w); } if(dij()){ puts("YES"); for(int i = 0; i < tot; i += 2){ if(val[i] == 0) val[i] = L + 1; printf("%d %d %d\n", to[i], to[i^1], val[i]); } } else puts("NO"); return 0; }
View Code

CodeForces 715B Complete The Graph 特殊的dijkstra