CF715B Complete The Graph 题解
Description.
给定一张带权无向图,有些边还没赋权,权值范围是 \([1,+\infty]\)。
构造一种方案,使得 \(s\) 到 \(t\) 最短路长度为 \(L\),输出方案。
Solution.
假装所有没赋权边全都为 \(1\) 然后跑一遍 dijkstra
,如果最段路已比 \(L\) 大了,就必定无解。
我们需要增加权值,我们需要魔改 dijkstra
。
每次增广的时候,如果当前这条边权值可以增加,那就增加,否则不变。
然后最后还需要 check
一下得到的最短路是不是 \(L\),因为可能不需要松弛最短路就已经比 \(L\) 小了。
Coding.
是啊……你就是那只鬼了……所以被碰到以后,就轮到我变成鬼了
//是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了……{{{
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;char c=getchar(),f=0;
for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=1;
for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
if(f) x=-x;
}/*}}}*/
struct edge{int to,w,f,nxt;}e[20005];int n,m,L,s,t,et=1,head[1005],ds[1005][2];
inline void adde(int x,int y,int w) {e[++et]=(edge){y,max(w,1),!w,head[x]},head[x]=et;}
inline void dijk(int s,int t,int fg)
{
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
q.push(make_pair(ds[s][fg]=0,s));for(int i=0;i<n;i++) ds[i][fg]=(i!=s)*1019260817;
for(;!q.empty();)
{
int x=q.top().second,w=q.top().first;q.pop();if(w^ds[x][fg]) continue;
for(int i=head[x],y;i;i=e[i].nxt)
{
y=e[i].to;if(fg&&e[i].f) e[i].w=e[i^1].w=max(e[i].w,ds[y][0]+L-ds[t][0]-ds[x][1]);
if(ds[y][fg]>ds[x][fg]+e[i].w) q.push(make_pair(ds[y][fg]=ds[x][fg]+e[i].w,y));
}
}
}
int main()
{
read(n),read(m),read(L),read(s),read(t);
for(int i=1,x,y,w;i<=m;i++) read(x),read(y),read(w),adde(x,y,w),adde(y,x,w);
dijk(s,t,0);if(ds[t][0]>L) return puts("NO"),0;else dijk(s,t,1);
if(ds[t][1]^L) return puts("NO"),0;else puts("YES");
for(int i=2;i<=et;i+=2) printf("%d %d %d\n",e[i+1].to,e[i].to,e[i].w);
return 0;
}