zzq讲的杂题

题目大意

有一张$n​$个点$m​$条边的简单正权无向图,$S​$到$T​$的最短路为$L​$,现在有一些边的边权未知,请输出任意一种满足题意的方案。

$n,m\le 500000​$.


题目分析

首先对于每一条边权未定的边,把它的边权设为1,处理出$dist_i​$表示在这种情况下,$T​$到$i​$的最短路距离。之后再从$S​$开始做dij,设$S​$到$u​$的最短路为$len_i​$,那么当前若以$u​$为起点增广一条边权未定的边$(u,v)​$,就将其边权设为$\max\{1,L-len_u-dist_v\}​$。最后若$T$的最短路不为$L$则无解。

关于第二次重设边权,如上处理之后在有解情况下显然第二次dij出的$len_i \le L$,那么剩下的就是考虑:可不可能把一条$L$的最短路给刷得更小了。

分步地看这个问题,我们最后一次进行重设边权操作时,等于说是钦定了一条过这个边的长度为$L$的路径(因为$len_i$是依靠重新设的边权做的最短路),也就是说一定是满足条件的最短路。反之如果这个做法无解,说明任意的未定边权的边都不在长为$L$的最短路上,那么也就没有任何影响。

注意如果(像我一样偷懒不刷完全图)那么需要判一判未经过的边。

时间复杂度:$O(n\log n)$

 #include<bits/stdc++.h>
typedef long long ll;
const int maxn = ;
const int maxm = ;
const ll INF = 1000000000000000000ll; struct Edge
{
int v;
ll val;
Edge(int a=, int b=):v(a),val(b) {}
}edges[maxm];
struct node
{
int x;
ll d;
node(int a=, ll b=):x(a),d(b) {}
bool operator < (node a) const
{
return d > a.d;
}
};
int n,m,L,S,T;
int edgeTot,head[maxn],nxt[maxm];
ll dis[maxn],len[maxn];
int dfn[maxn],tim;
std::priority_queue<node> q; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge()
{
int u = read()+, v = read()+, c = read();
edges[edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot, ++edgeTot;
edges[edgeTot] = Edge(u, c), nxt[edgeTot] = head[v], head[v] = edgeTot, ++edgeTot;
}
int main()
{
memset(head, -, sizeof head);
n = read(), m = read(), L = read(), S = read()+, T = read()+;
for (int i=; i<=m; i++) addedge();
memset(dis, 0x3f3f3f3f, sizeof dis);
tim = , q.push(node(T, )), dis[T] = ;
for (int tmp; q.size(); )
{
tmp = q.top().x, q.pop();
if (dfn[tmp]==tim) continue;
dfn[tmp] = tim;
for (int i=head[tmp]; i!=-; i=nxt[i])
{
int v = edges[i].v, c = edges[i].val?edges[i].val:;
if (dis[v] > dis[tmp]+c) dis[v] = dis[tmp]+c, q.push(node(v, dis[v]));
}
}
memset(len, 0x3f3f3f3f, sizeof len);
tim = , q.push(node(S, )), len[S] = ;
for (int tmp; q.size(); )
{
tmp = q.top().x, q.pop();
if (dfn[tmp]==tim) continue;
dfn[tmp] = tim;
if (tmp==T){
if (len[T]!=L) puts("NO");
else{
puts("YES");
for (int i=; i<=n; i++)
for (int j=head[i]; j!=-; j=nxt[j])
if (edges[j].v > i) printf("%d %d %lld\n",i-,edges[j].v-,edges[j].val?edges[j].val:INF);
}
return ;
}
for (int i=head[tmp]; i!=-; i=nxt[i])
{
if (!edges[i].val){
edges[i].val = edges[i^].val = std::max(L-len[tmp]-dis[edges[i].v], 1ll);
}
int v = edges[i].v, c = edges[i].val;
if (len[v] > len[tmp]+c) len[v] = len[tmp]+c, q.push(node(v, len[v]));
}
}
puts("NO");
return ;
}

END

【图论 思维】cf715B. Complete The Graph加强的更多相关文章

  1. CF715B. Complete The Graph

    CF715B. Complete The Graph 题意: 给一张 n 个点,m 条边的无向图,要求设定一些边的边权 使得所有边权都是正整数,最终 S 到 T 的最短路为 L 1 ≤ n ≤ 100 ...

  2. Codeforces 715B & 716D Complete The Graph 【最短路】 (Codeforces Round #372 (Div. 2))

    B. Complete The Graph time limit per test 4 seconds memory limit per test 256 megabytes input standa ...

  3. 【Codeforces】716D Complete The Graph

    D. Complete The Graph time limit per test: 4 seconds memory limit per test: 256 megabytes input: sta ...

  4. CodeForces 715B Complete The Graph 特殊的dijkstra

    Complete The Graph 题解: 比较特殊的dij的题目. dis[x][y] 代表的是用了x条特殊边, y点的距离是多少. 然后我们通过dij更新dis数组. 然后在跑的时候,把特殊边都 ...

  5. Codeforces 715B. Complete The Graph 最短路,Dijkstra,构造

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF715B.html 题解 接下来说的“边”都指代“边权未知的边”. 将所有边都设为 L+1,如果dis(S,T ...

  6. codeforces 715B:Complete The Graph

    Description ZS the Coder has drawn an undirected graph of n vertices numbered from 0 to n - 1 and m ...

  7. UESTC_小panpan学图论 2015 UESTC Training for Graph Theory<Problem J>

    J - 小panpan学图论 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) S ...

  8. 「CF716D」Complete The Graph「最短路」

    题意 给定一个\(n\)个点\(m\)条边的无向图,有一些边权暂时为\(0\),你需要分配一个\([1, 10^{18}]\)的数.最终使得\(s\)到\(t\)最短路为\(L\),输出一个可行的分配 ...

  9. CF716D Complete The Graph

    图论+构造 首先可以发现如果去除了可以改变权值的边,$s$到$t$的最短路若小于$l$,那么一定不行 若等于则直接将可改边权的边改为inf,输出即可 那么现在原图中的最短路是大于$l$的 因为每一条边 ...

随机推荐

  1. Java集合框架概述

    集合框架指的是容器类.Java中大量持有对象的方式有数组和容器类两种方式.数组相较于容器类的优点在于:①随机访问效率高:由于是连续的存储空间,可以计算地址直接访问 ②类型确定:数组在创建时即可确定元素 ...

  2. php锁定文本框内容的方法

    有时候我们希望表单中的文本框是只读的,让用户不能修改其中的信息,如<input type="text" name="zg" value="中国& ...

  3. Javascript 学习 Boolean

    构造函数 new Boolean(value) //构造函数 Boolean(value) //转换函数 参数 value 由布尔对象存放的值或者要转换成布尔值的值 返回值 当作为一个构造函数(带有运 ...

  4. collides with another import statement解决办法

    如我要导入的两个包名为: import com.tesla.gateway.core.filter.Filter import ch.qos.logbak.core.filter.Filter 这样就 ...

  5. CSS实现多重边框和内凹圆角

    CSS实现多重边框 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&q ...

  6. 跨平台图表控件TeeChart使用教程:导入XML数据

    TeeChart的最新版中包含了一个自动加载XML数据的新组件.这个组件的名字叫做TTeeXMLSource,用户可以在TeeXML.pas unit中找到这个组件. 加载XML图表所需的最小属性是& ...

  7. Android GreenDAO 3.0 不修改版本号的情况下增加、删除表、添加字段

    最近项目中使用了GreenDAO的3.0以上的版本,出现需要增加删除表的需求,刚开始用,发现官方对增加和删除的方法是每次去修改数据库版本号,版本一旦升级,那么原来数据库中的表会全部删除再重建.太麻烦, ...

  8. ASP.NET Core - VSCode安装和配置

    在深入了解ASP.NET Core之前先研究了下主要的两个开发工具(VS 2015和VS Code), VS 2015对Core的支持已经相当的完备,很多操作得到简化用起来很是方便.VS Code是微 ...

  9. 开源框架 epics,开源画面编辑软件 edm

    epics Experimental Physics and Industrial Control System 一套开源软件框架,实验物理和工业控制系统 http://www.aps.anl.gov ...

  10. C++ POD类型

    POD( Plain Old Data)概念: Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to m ...