传送门:>Here<

题意:给出一张带权无向图,其中有一些边权为0。要求将边权为0的边的边权重置为一个任意的正整数,使得从S到T的最短路为L。判断是否存在这种方案,如果存在输出任意一种

解题思路

  注意是最短路是L,而非存在一条路径为L。并且边权为0的边必须变为正整数,最小也得是1

  这题由于n=1000,所以可以稍微暴力一点……

  首先,先不加任何一条为0的边跑Dij,如果此时的最短路已经$< L$,那么后面的边无论怎么加都不会使最短路比当前的大了,因此无解

  此时最短路$\geq L$。然后考虑一条一条把边加进图里。每一条塞进图里的边权值都设为最小(也就是1)。如果加上了当前这条边使得最短路$< L$了,那么导致最短路变小的一定就是当前这一条边。因为除了通过当前这条边的路径以外其他路径都$\geq L$。所以我们可以修改这一条边的权值为$L-d[t]+1$,也就是把最短路凑成等于L。并且修改之后所有的路径依然$\geq L$。如果加上当前这一条边最短路依然$\geq L$,那么这条边就是废掉的,可以不管。所以我们需要做的,就是对于每一条使最短路$< L$的边都做此修改。最后判断最短路是否等于L即可。复杂度$O(m^2\ log\ n)$,非常巧妙~

Code

  注意应当把无法使路径变小的边权值设为1

/*By DennyQi*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
#define ERR {puts("NO");return 0;}
using namespace std;
typedef long long ll;
#define int long long
const int MAXN = ;
const int MAXM = ;
const int INF = 1e13;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) +(x << ) + c - '', c = getchar(); return x * w;
}
struct Edge{
int u,v,w;
}a[MAXM];
struct Node{
int idx,w;
};
inline bool operator < (const Node& a, const Node& b){
return a.w > b.w;
}
int N,M,L,S,T,x,y,z;
int first[MAXM*],nxt[MAXM*],to[MAXM*],cost[MAXM*],num_edge;
priority_queue <Node> q;
int d[MAXN],vis[MAXN];
inline void add(int u, int v, int w){
to[++num_edge] = v;
cost[num_edge] = w;
nxt[num_edge] = first[u];
first[u] = num_edge;
}
inline void Dijkstra(int s){
for(int i = ; i <= N; ++i) d[i] = INF;
memset(vis, , sizeof(vis));
d[s] = ;
q.push((Node){s, });
int u, v;
while(!q.empty()){
u = q.top().idx; q.pop();
if(vis[u]) continue; vis[u]=;
for(int i = first[u]; i; i = nxt[i]){
v = to[i];
if(d[u] + cost[i] < d[v]){
d[v] = d[u] + cost[i];
q.push((Node){v,d[v]});
}
}
}
}
main(){
// freopen(".in","r",stdin);
N=r,M=r,L=r,S=r,T=r;
for(int i = ; i <= M; ++i){
a[i].u=r, a[i].v=r, a[i].w=r;
if(a[i].w != ){
add(a[i].u,a[i].v,a[i].w);
add(a[i].v,a[i].u,a[i].w);
}
}
Dijkstra(S);
if(d[T] < L) ERR;
for(int i = ; i <= M; ++i){
if(a[i].w != ) continue;
a[i].w = ;
add(a[i].u,a[i].v,);
add(a[i].v,a[i].u,);
Dijkstra(S);
if(d[T] < L){
a[i].w = - d[T] + L;
cost[num_edge-] = - d[T] + L;
cost[num_edge] = - d[T] + L;
}
}
/* for(int i = 1; i <= M; ++i){
printf("%d %d %d\n", a[i].u,a[i].v,a[i].w);
}
printf("d[%d] = %d\n",T,d[T]);*/
Dijkstra(S);
if(d[T] != L) ERR;
puts("YES");
for(int i = ; i <= M; ++i){
printf("%lld %lld %lld\n", a[i].u,a[i].v,a[i].w);
}
return ;
}

Codeforces715 B. Complete The Graph的更多相关文章

  1. 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 ...

  2. CF715B. Complete The Graph

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

  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

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

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

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

  7. Codeforces Round #372 (Div. 1) B. Complete The Graph (枚举+最短路)

    题目就是给你一个图,图中部分边没有赋权值,要求你把无权的边赋值,使得s->t的最短路为l. 卡了几周的题了,最后还是经群主大大指点……做出来的…… 思路就是跑最短路,然后改权值为最短路和L的差值 ...

  8. Codeforces Round #372 (Div. 1) B. Complete The Graph

    题目链接:传送门 题目大意:给你一副无向图,边有权值,初始权值>=0,若权值==0,则需要把它变为一个正整数(不超过1e18),现在问你有没有一种方法, 使图中的边权值都变为正整数的时候,从 S ...

  9. 715B Complete The Graph

    传送门 题目大意 给出一个图,一些边带权,另一些边等待你赋权(最小赋为1).请你找到一种赋权方式,使得 s 到 t 的最短路为 L n ≤ 1e3 ,m ≤ 1e4 ,L ≤ 1e9 分析 二分所有边 ...

随机推荐

  1. 几何学观止(Lie群部分)

    上承这个页面,这次把Lie群的部分写完了 几何学观止-微分几何部分(20181102).pdf 我觉得其他部分(尤其是代数几何部分)我目前没有把握写得令自己满意,总之希望在毕业前能写完吧. 这次调整了 ...

  2. 启发式合并 splay合并 线段树合并基础

    Gold is everywhen! - somebody 启发式合并 将小的集合一个个插入到大的集合. 每次新集合大小至少比小集合大一倍,因此每个元素最多合并\(\log n\)次,总复杂度为\(n ...

  3. Python—生成器

    列表生成式 现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,你怎么实现? >>> a = [i+1 for i in r ...

  4. Python是如何进行内存管理

    三个方面:一对象的引用计数机制,二垃圾回收机制,三内存池机制 一.对象的引用计数机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数. 引用计数增加的情况: 1,一个对象分 ...

  5. elk之查询方式(4种)

    es 在查询时, 可以指定搜索类型为下面四种: QUERY_THEN_FETCH QUERY_AND_FEATCH DFS_QUERY_THEN_FEATCH DFS_QUERY_AND_FEATCH ...

  6. javaScript 删除本地cookie删不了

    一.js删除本地cookie无法删除 今天发现自己真的蠢爆了! 以下为cookie定义: 1.设置Cookie的key   2.设置Cookie的key-value值   3.过期时间-自定义(一般在 ...

  7. ElastichSearch漏洞

    Ubuntu服务器被黑经历(ElastichSearch漏洞) 起因 最近我们的一台Ubuntu阿里云服务器一直提示有肉鸡行为,提示了好几天,开始并没有关注,然后连续几天后发现应该是个大问题啊.很可能 ...

  8. 【问题解决方案】The MathType Dll cannot be found 问题解决方案

    先贴几个可能的方法: 如何解决MathPage.wll或MathType.dll文件找不到问题 The MathType Dll cannot be found 问题解决办法 如果还搞不定,试试卸载重 ...

  9. sqlServer问题记录

    1.sql 2008 无法绑定由多个部分绑定的标示符 连接中的多个表中存在同名字段,通过设置别名访问即可 2.远程无法连接到sqlserver 计算机管理->服务与应用程序->SQL Se ...

  10. sql学习内容记录

    1.left函数 left(字段,长度):获取指定字段左侧的数据,类似substring函数 2.union / union all 将多个记录合并成一个完整的数据集 3.insert into se ...