原文链接https://www.cnblogs.com/zhouzhendong/p/CF715B.html

题解

接下来说的“边”都指代“边权未知的边”。

将所有边都设为 L+1,如果dis(S,T) < L ,那么必然无解。

将所有边都设为 1 ,如果 dis(S,T) > L ,那么必然无解。

考虑将任意一条边的权值+1,则 dis(S,T) 会 +0 或者 +1 。

如果将所有边按照某一个顺序不断+1,直到所有边的权值都是L+1了,那么在这个过程中,dis(S,T) 是递增的,而且一定在某一个时刻 dis(S,T) = L。

这样的话我们就可以二分答案+dijkstra解决这个问题了。

时间复杂度 $O(n\log (n+m) \log (mL))$ 。

事实上有更优秀的做法(我并没有想到),懒得写了,给个链接:

https://blog.csdn.net/aufeas/article/details/52916704

代码

  1. #include <bits/stdc++.h>
  2. #define clr(x) memset(x,0,sizeof (x))
  3. using namespace std;
  4. typedef long long LL;
  5. #define pii pair <int,int>
  6. LL read(){
  7. LL x=0,f=0;
  8. char ch=getchar();
  9. while (!isdigit(ch))
  10. f|=ch=='-',ch=getchar();
  11. while (isdigit(ch))
  12. x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
  13. return f?-x:x;
  14. }
  15. const int N=1005,M=10005,INF=1e9+5;
  16. int n,m,L,S,T;
  17. struct Edge{
  18. int x,y,z;
  19. }e[M];
  20. struct Graph{
  21. int cnt,y[M*2],z[M*2],nxt[M*2],fst[N];
  22. void clear(){
  23. cnt=1,clr(fst);
  24. }
  25. void add(int a,int b,int c){
  26. y[++cnt]=b,nxt[cnt]=fst[a],fst[a]=cnt,z[cnt]=c;
  27. }
  28. void update(int id,int v){
  29. z[id<<1]=z[id<<1|1]=v;
  30. }
  31. }g;
  32. vector <int> eid;
  33. int dis[N],vis[N];
  34. int Dijkstra(){
  35. static priority_queue <pii,vector <pii>,greater <pii> > Q;
  36. while (!Q.empty())
  37. Q.pop();
  38. for (int i=1;i<=n;i++)
  39. dis[i]=INF,vis[i]=0;
  40. dis[S]=0;
  41. Q.push(make_pair(dis[S],S));
  42. while (!Q.empty()){
  43. pii p=Q.top();
  44. Q.pop();
  45. int x=p.second;
  46. if (vis[x]||dis[x]!=p.first)
  47. continue;
  48. vis[x]=1;
  49. for (int i=g.fst[x];i;i=g.nxt[i]){
  50. int y=g.y[i],z=g.z[i];
  51. if (!vis[y]&&dis[x]+z<dis[y]){
  52. dis[y]=dis[x]+z;
  53. Q.push(make_pair(dis[y],y));
  54. }
  55. }
  56. }
  57. return dis[T];
  58. }
  59. int check(LL v){
  60. for (auto i : eid){
  61. LL d=min(v,(LL)L);
  62. g.update(i,d+1);
  63. v-=d;
  64. }
  65. return Dijkstra()<=L;
  66. }
  67. int main(){
  68. n=read(),m=read(),L=read(),S=read()+1,T=read()+1;
  69. g.clear();
  70. for (int i=1;i<=m;i++){
  71. int x=read()+1,y=read()+1,z=read();
  72. e[i].x=x,e[i].y=y,e[i].z=z;
  73. g.add(x,y,z);
  74. g.add(y,x,z);
  75. if (!z)
  76. eid.push_back(i);
  77. }
  78. for (auto i : eid)
  79. g.update(i,INF);
  80. if (Dijkstra()<L)
  81. return puts("NO"),0;
  82. for (auto i : eid)
  83. g.update(i,1);
  84. if (Dijkstra()>L)
  85. return puts("NO"),0;
  86. LL l=0,r=(LL)L*(int)eid.size(),mid,ans=l;
  87. while (l<=r){
  88. mid=(l+r)>>1;
  89. if (check(mid))
  90. l=mid+1,ans=mid;
  91. else
  92. r=mid-1;
  93. }
  94. for (auto i : eid){
  95. LL d=min(ans,(LL)L);
  96. e[i].z=d+1;
  97. ans-=d;
  98. }
  99. puts("YES");
  100. for (int i=1;i<=m;i++)
  101. printf("%d %d %d\n",e[i].x-1,e[i].y-1,e[i].z);
  102. return 0;
  103. }

  

Codeforces 715B. Complete The Graph 最短路,Dijkstra,构造的更多相关文章

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

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

  2. Codeforces.567E.President and Roads(最短路 Dijkstra)

    题目链接 \(Description\) 给定一张有向图,求哪些边一定在最短路上.对于不一定在最短路上的边,输出最少需要将其边权改变多少,才能使其一定在最短路上(边权必须为正,若仍不行输出NO). \ ...

  3. Codeforces.1051F.The Shortest Statement(最短路Dijkstra)

    题目链接 先随便建一棵树. 如果两个点(u,v)不经过非树边,它们的dis可以直接算. 如果两个点经过非树边呢?即它们一定要经过该边的两个端点,可以直接用这两个点到 u,v 的最短路更新答案. 所以枚 ...

  4. Codeforces Gym101502 I.Move Between Numbers-最短路(Dijkstra优先队列版和数组版)

    I. Move Between Numbers   time limit per test 2.0 s memory limit per test 256 MB input standard inpu ...

  5. 715B Complete The Graph

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

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

  7. ACM - 最短路 - CodeForces 295B Greg and Graph

    CodeForces 295B Greg and Graph 题解 \(Floyd\) 算法是一种基于动态规划的算法,以此题为例介绍最短路算法中的 \(Floyd\) 算法. 我们考虑给定一个图,要找 ...

  8. 【Codeforces】716D Complete The Graph

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

  9. 算法学习笔记(三) 最短路 Dijkstra 和 Floyd 算法

    图论中一个经典问题就是求最短路.最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划.这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是 ...

随机推荐

  1. Flask上下文管理、session原理和全局g对象

    一.一些python的知识 1.偏函数 def add(x, y, z): print(x + y + z) # 原本的写法:x,y,z可以传任意数字 add(1,2,3) # 如果我要实现一个功能, ...

  2. luogu P1250 种树

    我来总结一下最常用的两种办法 1.贪心 2.差分约束 那么我们先来讲,贪心版<种树> 大家可能知道有一个题和这个类似,那个是钉钉子而这个是种树 我们可以借用钉钉子的思路来想,首先这个是让你 ...

  3. 【XSY3048 】Polynominal 数学

    题目描述 给你三个正整数 \(a,b,c\),求有多少个系数均为非负整数的多项式 \(f(x)\) 满足 \(f(a)=b\) 且 \(f(b)=c\) \(a,b,c\leq {10}^{18}\) ...

  4. Linux squid代理

    代理的作用: 共享网络 : 加快访问速度,节约通信带宽 : 防止内部主机受到攻击 : 限制用户访问,完善网络管理: 标准代理: 首先要在内部主机指定代理服务器的IP和port,然后通过代理服务器访问外 ...

  5. 分布式监控系统开发【day38】:报警阈值程序逻辑解析(三)

    一.需求讨论 1.请问如何解决延迟问题 1000台机器,每1分钟循环一次但是刚好第一次循环第一秒刚处理完了,结果还没等到第二分钟又出问题,你那必须等到第二次循环,假如我这个服务很重要必须实时知道,每次 ...

  6. 金融量化分析【day110】:NumPy-切片和索引

    一.索引和切片 1.数组和标量之间的运算 2.同样大小的数组之间的运算 3.数组索引 4.数组切片 1.一维数组 2.多维数组 二.布尔索引 1.问题 给一个数组,选出数组中所有大于5的数 1.答案 ...

  7. DirectX11 With Windows SDK--01 DirectX11初始化

    前言 由于个人觉得龙书里面第4章提供的Direct3D 初始化项目封装得比较好,而且DirectX SDK Samples里面的初始化程序过于精简,不适合后续使用,故选择了以Init Direct3D ...

  8. 删除对象的某个属性 delete

    有时候我们可能会遇到需要删除一个对象的某个属性的这种情况,保留剩下的,不想遍历,那我们就可以使用delete操作符, let obj = { a: 1, b: 2, c: 3 } delete obj ...

  9. 终止ajax异步请求——abort()

    var xhr=$.ajax(); xhr.abort();//在终止之前要确定xhr不为空

  10. Jenkins--发送邮件配置

    使用Jenkins可以进行构建,并可以发送邮件.今天我们来讲一下邮件的配置. 首先:下载安装插件: 进入[Jenkins-系统管理-插件管理-可选插件],搜索“Email Extension”进行安装 ...