考虑先把所有边填成1,这样不会影响最终答案,因为每条边都必须填一个正整数
接下来只需要在此基础上增大边权即可
我们先把填1的图做一遍dijkstra,然后再把原图做一遍dijkstra,第二次的时候如果遇到一条边
(
u
,
v
)
(u,v)
(u,v)没有权值,那就把边权设为
m
a
x
(
1
,
L
−
d
2
[
u
]
−
d
1
[
v
]
)
max(1,L-d2[u]-d1[v])
max(1,L−d2[u]−d1[v]),其中
d
2
d2
d2表示当前最短路,
d
1
d1
d1表示第一次跑出来的,
v
v
v到
t
t
t的最短路,这样相当于确定了一条长为
L
L
L的最短路,并且由于我们每次改边权都确定了一条最短路,所以进行修改的边之间不会相互影响,则这样可以构造出答案
如果这样做完
s
s
s到
t
t
t的最短路仍然不等于
L
L
L则显然无解
Code:
#include<bits/stdc++.h>
#define mp make_pair
#define ll long long
#define fi first
#define se second
using namespace std;
inline int read(){
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-f;ch=getchar();}
while(isdigit(ch)) {res=(res<<1)+(res<<3)+(ch^48);ch=getchar();}
return res*f;
}
int L,s,t;
namespace Shortest_Path1{
const int N=2e5+5;
int vis[N],head[N],nxt[N],tot=0;ll d[N],c[N];
inline void add(int x,int y,ll z){vis[++tot]=y;nxt[tot]=head[x];head[x]=tot;c[tot]=z;}
int pt[N];
inline void dijkstra(){
priority_queue<pair<ll,int> >q;
memset(d,0x3f,sizeof(d));
memset(pt,0,sizeof(pt));
d[t]=0;q.push(mp(0,t));
while(!q.empty()){
int x=q.top().se;q.pop();pt[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=vis[i],z=c[i];
if(pt[y]) continue;
if(z==0) z=1;
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(mp(-d[y],y));
}
}
}
}
}
#define S1 Shortest_Path1
int ans[200005];
namespace Shortest_Path2{
const int N=2e5+5;
int vis[N],head[N],nxt[N],tot=0,id[N];
ll c[N];
inline void add(int x,int y,ll z,int w){vis[++tot]=y;id[tot]=w;nxt[tot]=head[x];head[x]=tot;c[tot]=z;}
ll d[N];int pt[N];
inline void dijkstra(){
priority_queue<pair<ll,int> >q;
memset(d,0x3f,sizeof(d));
memset(pt,0,sizeof(pt));
d[s]=0;q.push(mp(0,s));
while(!q.empty()){
int x=q.top().se;q.pop();pt[x]=1;
for(int i=head[x];i;i=nxt[i]){
int y=vis[i],z=c[i];
if(pt[y]) continue;
if(z==0) z=max(1ll,L-d[x]-S1::d[y]),ans[id[i]]=z;
if(d[y]>d[x]+z){
d[y]=d[x]+z;
q.push(mp(-d[y],y));
}
}
}
}
}
#define S2 Shortest_Path2
int xx[200005],yy[200005];
int main(){
int n=read(),m=read();L=read(),s=read()+1,t=read()+1;
for(int i=1;i<=m;i++){
int x=read()+1,y=read()+1,z=read();
xx[i]=x-1,yy[i]=y-1;ans[i]=z;
S1::add(x,y,z);S1::add(y,x,z);
S2::add(x,y,z,i);S2::add(y,x,z,i);
}
S1::dijkstra();
S2::dijkstra();
if(S2::d[t]!=L) return puts("NO"),0;
puts("YES");
for(int i=1;i<=m;i++)
cout<<xx[i]<<" "<<yy[i]<<" "<<ans[i]<<"\n";
return 0;
}