1. 程式人生 > 其它 >CF715B Complete The Graph 題解

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;
}