ZS the Coder has drawn an undirected graph of n vertices numbered from 0 to n - 1 and m edges between them. Each edge of the graph is weighted, each weight is a positive integer.
The next day, ZS the Coder realized that some of the weights were erased! So he wants to reassign positive integer weight to each of the edges which weights were erased, so that the length of the shortest path between vertices s and t in the resulting graph is exactly L. Can you help him?
The first line contains five integers n, m, L, s, t (2 ≤ n ≤ 1000, 1 ≤ m ≤ 10 000, 1 ≤ L ≤ 109, 0 ≤ s, t ≤ n - 1, s ≠ t) — the number of vertices, number of edges, the desired length of shortest path, starting vertex and ending vertex respectively.
Then, m lines describing the edges of the graph follow. i-th of them contains three integers, ui, vi, wi(0 ≤ ui, vi ≤ n - 1, ui ≠ vi, 0 ≤ wi ≤ 109). ui and vi denote the endpoints of the edge and wi denotes its weight. If wi is equal to 0 then the weight of the corresponding edge was erased.
It is guaranteed that there is at most one edge between any pair of vertices.
Print "NO" (without quotes) in the only line if it's not possible to assign the weights in a required way.
Otherwise, print "YES" in the first line. Next m lines should contain the edges of the resulting graph, with weights assigned to edges which weights were erased. i-th of them should contain three integers ui, vi and wi, denoting an edge between vertices ui and vi of weight wi. The edges of the new graph must coincide with the ones in the graph from the input. The weights that were not erased must remain unchanged whereas the new weights can be any positive integer not exceeding 1018.
The order of the edges in the output doesn't matter. The length of the shortest path between s and t must be equal to L.
If there are multiple solutions, print any of them.
5 5 13 0 4 0 1 5 2 1 2 3 2 3 1 4 0 4 3 4
YES 0 1 5 2 1 2 3 2 3 1 4 8 4 3 4
2 1 123456789 0 1 0 1 0
YES 0 1 123456789
2 1 999999999 1 0 0 1 1000000000
NO
題意:n個點,m條邊,起點s,終點t,當邊的權值爲0時,可以改變爲任意的權值,求是否可以通過改變權值爲0的邊,使s到t的最短路長度爲L
由於求的是最短路首先想到最短路問題,
當改變一條邊的權值後,s到t的最短路也會發生變化,於是此時最短路要重新計算
共有兩種情況:
1.不經過權值爲0的邊,此時的最短路已經<L,那麼這種情況肯定是輸出NO
2不經過權值爲0的邊,此時的最短路>=L,此時就要考慮加上這些權值爲0的邊,使得最短路變小,滿足條件
當經過一條權值爲0的邊,可以先將該邊賦權值爲1(因爲題目要求邊權爲正整數),求出最短距離,如果此時的最短距離<L,表示此時該邊一定在最短路徑中,將該邊權改爲L-dis[t]+1,使最短路爲L
然後暴力將每一個權值爲0的邊加入圖即可
若加入所有邊後,此時的最短距離仍>L,輸出NO
否則,輸出YES
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e3+20;
int n,m,s,t,L,first[N],tot;
ll dis[N];
bool vis[N];
struct node
{
int v,next,flag;
ll w;
} e[N*20];
void add(int u,int v,ll w)
{
e[tot].v=v;
e[tot].w=w;
if(w==0)e[tot].flag=1;
e[tot].next=first[u];
first[u]=tot++;
}
struct point
{
point(int a,ll b)
{
x=a,val=b;
}
int x;
ll val;
bool friend operator <(point A,point B)
{
return A.val>B.val;
}
};
void dijkstra()
{
for(int i=0;i<n;i++)dis[i]=1000000000000000000;
priority_queue<point>q;
dis[s]=0;
q.push(point(s,0));
while(!q.empty())
{
point u=q.top();
q.pop();
if(dis[u.x]<u.val)continue;
for(int i=first[u.x]; ~i; i=e[i].next)
{
int v=e[i].v;
if(e[i].w==0)continue;
if(dis[v]>dis[u.x]+e[i].w)
{
dis[v]=dis[u.x]+e[i].w;
q.push(point(v,dis[v]));
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
mem(first,-1);
int u,v;
ll w;
cin>>n>>m>>L>>s>>t;
for(int i=0; i<m; i++)
{
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
dijkstra();
if(dis[t]<L)puts("NO");//不經過權值爲0的邊,最短路已經<L
else//>=L的情況
{
for(int i=0;i<tot;i+=2)
{
if(!e[i].flag)continue;
e[i].w=e[i^1].w=1;
dijkstra();//暴力將每條邊都加入圖,求得最短路
if(dis[t]<L)//將最小距離補夠L
e[i].w=e[i^1].w=L-dis[t]+1;
}
if(dis[t]>L)puts("NO");//加完所有邊後距離仍>L
else//不會出現<L的情況,因爲每次都補夠了L
{
puts("YES");
for(int i=0;i<tot;i+=2)
printf("%d %d %lld\n",e[i^1].v,e[i].v,e[i].w);
}
}
return 0;
}