CF716D Complete The Graph
Posted huangchenyan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF716D Complete The Graph相关的知识,希望对你有一定的参考价值。
图论+构造
首先可以发现如果去除了可以改变权值的边,$s$到$t$的最短路若小于$l$,那么一定不行
若等于则直接将可改边权的边改为inf,输出即可
那么现在原图中的最短路是大于$l$的
因为每一条边是都要加入图中的,而且每条边边权至少为1
那么可以不断向图中加入权值为1的边,并且在加边的过程中不断跑最短路
如果加完当前的边,$s$到$t$的最短路小于l的话,将这条边权值增加
剩下的边边权改为inf即可
简单证明这种做法
首先考虑加入1边后,最短路依然大于$l$,那么继续使最短路减小
再考虑加入1边后,最短路小于$l$
因为在加入这条边之前最短路大于l,那么加入这条边后,最短路肯定经过这条边
而增加边权之后,最短路还是比之前的小,那么最短依然经过这条边
不会出现增加了这条边的边权之后,最短路不经过这条边的情况
那么得到的图最短路必定为l
#include <bits/stdc++.h> #define ll long long #define inf (ll)1e17; using namespace std; const int MAXN=20100; int n,m,l,s,t,tot; int first[1100],nxt[MAXN],point[MAXN]; int vi[1100]; ll d[1100],len[MAXN]; struct node int u,v; ll l; sh[MAXN]; void add_edge(int x,int y,int z) tot++; nxt[tot]=first[x]; first[x]=tot; point[tot]=y; len[tot]=z; void spfa()//最短路 queue <int> q; for (int i=0;i<n;i++) d[i]=inf; d[s]=0; vi[s]=1; q.push(s); while (!q.empty()) int f; f=q.front(); q.pop(); vi[f]=0; for (int i=first[f];i!=-1;i=nxt[i]) int u; u=point[i]; if (d[u]>d[f]+len[i]) d[u]=d[f]+len[i]; if (!vi[u]) vi[u]=1; q.push(u); int main() tot=-1; memset(first,-1,sizeof(first)); memset(nxt,-1,sizeof(nxt)); scanf("%d%d%d%d%d",&n,&m,&l,&s,&t); for (int i=1;i<=m;i++) scanf("%d%d%lld",&sh[i].u,&sh[i].v,&sh[i].l); if (sh[i].l==0) continue; add_edge(sh[i].u,sh[i].v,sh[i].l); add_edge(sh[i].v,sh[i].u,sh[i].l); spfa(); if (d[t]<l) printf("NO\n"); return 0; if (d[t]==l)//注意 printf("YES\n"); for (int i=1;i<=m;i++) if (sh[i].l==0) sh[i].l=inf; printf("%d %d %lld\n",sh[i].u,sh[i].v,sh[i].l); return 0; int wh; for (int i=1;i<=m;i++) if (sh[i].l==0) add_edge(sh[i].u,sh[i].v,1); add_edge(sh[i].v,sh[i].u,1); spfa(); if (d[t]>l) sh[i].l=1; continue; sh[i].l=1+l-d[t]; wh=i; break; tot=-1; memset(first,-1,sizeof(first)); memset(nxt,-1,sizeof(nxt)); for (int i=wh+1;i<=m;i++) if (sh[i].l==0) sh[i].l=inf; for (int i=1;i<=m;i++) add_edge(sh[i].u,sh[i].v,sh[i].l); add_edge(sh[i].v,sh[i].u,sh[i].l); spfa(); if (d[t]!=l) printf("NO\n"); return 0; printf("YES\n"); for (int i=1;i<=m;i++) printf("%d %d %lld\n",sh[i].u,sh[i].v,sh[i].l);
以上是关于CF716D Complete The Graph的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 715B. Complete The Graph 最短路,Dijkstra,构造
codeforces 715B:Complete The Graph
Codeforces Round #372 (Div. 1) B. Complete The Graph