[CF715B] Complete The Graph

前言

多写写构造题是有好处的

题目

CF

洛谷

讲解

我们首先考虑无解

对于每条不确定的边,我们令它们的权值为\(1\)

如果此时最短路的结果大于\(L\),无解

等于\(L\)可直接输出

现在我们考虑如何让最短路从一个比\(L\)小的值变为\(L\)

我们记\(L\)与这个值的差为\(ADD\)

我们要做的就是让\(s\)\(t\)的最短路增加\(ADD\)

这样貌似不太好想,但是如果让所有点全部加上\(ADD\)呢?

豁然开朗!

我们直接在跑\(dij\)的时候

对于每条可修改边增加权值,当然这个值是可以直接算出来的

如果通过这样的操作都不是\(L\),输出\(NO\)

代码

int tot;
int U[MAXM],V[MAXM],head[MAXN];
LL W[MAXM];
bool c[MAXM];
struct edge
{
	int v,ID,nxt;
}e[MAXM << 1];
void Add_Edge(int x,int y,int ID)
{
	e[++tot].v = y;
	e[tot].nxt = head[x];
	e[tot].ID = ID;
	head[x] = tot;
}
void Add_Double_Edge(int x,int y,int ID)
{
	Add_Edge(x,y,ID);
	Add_Edge(y,x,ID);
}

LL dis[2][MAXN];
struct node
{
	int x;
	LL val;
	node(){}
	node(int x1,LL val1){
		x = x1;
		val = val1;
	}
	bool operator < (const node &px)const{
		return val > px.val;
	}
};
LL ADD;
void dij(int x)
{
	for(int i = 0;i < n;++ i) dis[x][i] = INF;
	priority_queue<node> q;
	q.push(node(s,dis[x][s] = 0));
	while(!q.empty())
	{
		node t = q.top(); q.pop();
		if(t.val > dis[x][t.x]) continue;
		for(int i = head[t.x]; i ;i = e[i].nxt)
		{
			if(!x && t.val + W[e[i].ID] < dis[x][e[i].v])
				q.push(node(e[i].v,dis[x][e[i].v] = t.val + W[e[i].ID]));
			if(x)
			{
				if(c[e[i].ID]) W[e[i].ID] += Max(0ll,ADD - (t.val + W[e[i].ID] - dis[0][e[i].v]));
				if(t.val + W[e[i].ID] < dis[x][e[i].v]) q.push(node(e[i].v,dis[x][e[i].v] = t.val + W[e[i].ID]));
			}
		}
	}
}
void NO()
{
	printf("NO");
	exit(0);
}
void print()
{
	printf("YES\n");
	for(int i = 1;i <= m;++ i)
	{
		Put(U[i],' ');
		Put(V[i],' ');
		Put(W[i],'\n');
	}
	exit(0);
}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); m = Read(); L = Read(); s = Read(); t = Read();
	for(int i = 1;i <= m;++ i)
	{
		U[i] = Read();
		V[i] = Read();
		W[i] = Read();
		if(!W[i]) c[i] = 1,W[i] = 1;
		Add_Double_Edge(U[i],V[i],i);
	}
	dij(0);
	if(dis[0][t] > L) NO();
	else if(dis[0][t] == L) print();
	ADD = L - dis[0][t];
	dij(1);
	if(dis[1][t] < L) NO();
	print();
	return 0;
}
posted @ 2020-12-22 21:56  皮皮刘  阅读(65)  评论(0编辑  收藏  举报