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. Murano Weekly Meeting 2015.11.04

    Meeting time: 2015.November.4th 1:00~2:00 Chairperson:  Serg Melikyan, PTL from Mirantis Meeting sum ...

  2. 细讲递归(recursion)

    首先先对递归进行入门. 递归是以自相似的方式重复项目的过程.在编程语言中,如果程序允许您在同一函数内调用函数,则称其为函数的递归调用. 简而言之,递归就是函数的自身调用.可以看看下面的递归使用: vo ...

  3. Hadoop学习笔记(3) Hadoop文件系统二

    1 查询文件系统 (1) 文件元数据:FileStatus,该类封装了文件系统中文件和目录的元数据,包括文件长度.块大小.备份.修改时间.所有者以及版权信息.FileSystem的getFileSta ...

  4. 在CentOS上配置Tomcat服务脚本

    #!/bin/bash # chkconfig: - 85 15 # description: Tomcat Server basic start/shutdown script # processn ...

  5. Visual Studio无法推送提交到Github的解决方法

    前言 当出现Visual Studio推送变更失败时,卸载系统中所有Git以及Visual Studio 的Git工具再重装即可 前情概要 今天由于要尝试使用RabbitMQ,所以打算先在本地做些小D ...

  6. $.ajax显示进度条

  7. (二)JavaScript之[函数]与[作用域]

    3].函数 /** * 事件驱动函数. * 函数执行可重复使用的代码 * * 1.带参的函数 * 2.带返回值的函数 * 3.局部变量 * * 4.全局变量 * 在函数外的:不用var声明,未声明直接 ...

  8. Oracle数据表比较记录差异(转)

    liuyx_know|七级 你可以参照一下Oracle的UNION [ALL], INTERSECT, MINUS操作符,至于你的问题你可以使用MINUS操作符,语句如下: SELECT * FROM ...

  9. javascript中的循环引用对象处理

    先说明一下什么是循环引用对象: var a={"name":"zzz"}; var b={"name":"vvv"}; ...

  10. ie6下按钮下边框消失不显示的问题

    最近网站做改版,又发现一个ie6奇葩的问题,就一个很普通带边框的按钮,但在ie6中下边框不显示,ie7没有测试不知道是不是也不显示,其他浏览器正常 代码和预览效果如下: <style> b ...