Codeforces Round #372 (Div. 1) B. Complete The Graph
题目链接:传送门
题目大意:给你一副无向图,边有权值,初始权值>=0,若权值==0,则需要把它变为一个正整数(不超过1e18),现在问你有没有一种方法,
使图中的边权值都变为正整数的时候,从 S 到 T 的最短路恰好等于 L。
若没有输出 "NO",否则输出 "YES",同时输出新图中的所有边权值。
题目思路:二分+最短路(spfa or dijkstra)
闲谈:先%一发杜教,思路来源于看他的代码。然后蒟蒻spfa 982ms,杜教 dijkstra 93ms(毕竟1000个点,严格nlogn,spfa不稳定)
详细方法:
以下把题目中权值为0 的边称为 重构边 ,
无穷大设为1e9+1(因为 L 最大1e9,所以只要重构边权值为1e9+1,则任何经过该重构边的路径均不合法,因为>L)
题目要求所有边都要为正,那么我们验证时首先验证 重构边 权值为 1 的情况。
若此时从 S 到 T 的最短路 >L,则为NO
因为我们在题目要求范围里无法找到一条路径使 S 到 T 的最短路更短,所以不成立
再验证所有重构边 权值为 无穷大的情况。
若此时从 S 到 T 的最短路 <L,同样为NO
因为重构边设为无穷大之后,最短路只会走原图上的 非重构边,而这些边权值是不能改变的,及时重构边边权减小,
也只会使 最短路变得更短,所以不合法
这就是不合法的情况,除此之外的所有情况都会找到一种重构方法使题目有解。
上面第一种方法如果最短路<L,则可通过增加重构边边权的方法使最短路==L,第二种情况同理可减小边权使之成立
分割线/***----------------------------------------------------------------------------------------------------------------------***/
现在是如何找到一种边权分配方法使最短路==L
首先我们要弄明白一个结论
1.如果最短路不经过重构边(对应上面第二种情况)且最短路恰等于L,则重构边边权任意正整数。
2.如果最短路经过重构边{
无论最短路==L的路径有多少条,我们只需找到一条路径即可,其他路径上的重构边权值就算设为无穷大
对题目没有影响(因为已经找到一条)。我们只需要把选好的这条路径上的重构边边权设置好就行。
}
那么怎样设置边权?
可能你会问为什么不先找一条路径?其实我们只需要不断给每条边分配边权并且匹配最短路是否合法就行。
也就是说我们给每条重构边机会,如果不行,把它设为无穷大,否则分配边权给它看它是否能满足我们最短路的要求。
这样会很简单也不会出错。
设置边权的过程用二分来实现,二分的值是所有边的权值总和。然后从给每一条边分配权值,如果最短路==L,则成功
否则如果最短路<L,增加边权。如果最短路>L,减少边权。
最短路用 spfa or dijkstra 即可。此题点少,dijkstra很快。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cmath> 5 #include <algorithm> 6 #include <cstring> 7 #include <stack> 8 #include <cctype> 9 #include <queue> 10 #include <string> 11 #include <vector> 12 #include <set> 13 #include <map> 14 #include <climits> 15 #define lson rt<<1,l,mid 16 #define rson rt<<1|1,mid+1,r 17 #define fi first 18 #define se second 19 #define ping(x,y) ((x-y)*(x-y)) 20 #define mst(x,y) memset(x,y,sizeof(x)) 21 #define mcp(x,y) memcpy(x,y,sizeof(y)) 22 using namespace std; 23 #define gamma 0.5772156649015328606065120 24 #define mod 1000000007 25 #define inf 0x3f3f3f3f 26 #define N 1005050 27 #define maxn 20005 28 typedef pair<int,int> PII; 29 typedef long long LL; 30 31 int n,m,k,x,y,v; 32 int S,T,L; 33 int head[N],hcnt; 34 struct Node{ 35 int to,nxt,v; 36 }node[maxn]; 37 int d[N],vis[N],s[maxn]; 38 vector<int>eg; ///存重构边 39 queue<int>q; 40 int spfa(){ 41 for(int i=0;i<n;++i) d[i]=(int)1e9+1; d[S]=0; 42 mst(vis,0); q.push(S); 43 while(!q.empty()){ 44 int x=q.front();q.pop(); vis[x]=0; 45 for(int i=head[x];~i;i=node[i].nxt){ 46 int e=node[i].to; 47 if(d[e]>d[x]+node[i].v){ 48 d[e]=d[x]+node[i].v; 49 if(!vis[e]){vis[e]=1;q.push(e);} 50 } 51 } 52 } 53 return d[T]; 54 } 55 int check(LL sum){ ///判断是否合法 56 for(int u:eg){ 57 node[u].v=node[u|1].v=1+min(sum,1000000000ll); 58 ///给每个重构边分配权值 59 sum-=node[u].v-1; 60 } 61 return spfa(); 62 } 63 inline void add(int x,int y,int v){ 64 node[hcnt].to=y;node[hcnt].nxt=head[x];node[hcnt].v=v;head[x]=hcnt++; 65 } 66 int main(){ 67 int i,j,group; 68 mst(head,-1); 69 scanf("%d%d%d%d%d",&n,&m,&L,&S,&T); 70 for(i=1;i<=m;++i){ 71 scanf("%d%d%d",&x,&y,&v); 72 if(!v)eg.push_back(hcnt); 73 s[hcnt]=x; 74 add(x,y,v); 75 add(y,x,v); 76 } 77 LL l=0,r=eg.size()*LL(1e9); 78 if(check(0)>L||check(r)<L)return 0*printf("NO\n"); 79 LL ans; 80 while(l<=r){ 81 LL mid=l+r>>1,temp=check(mid); 82 if(temp>L)ans=mid,r=mid-1; 83 else if(temp<L)l=mid+1; 84 else break; 85 } 86 printf("YES\n"); 87 for(i=0;i<m*2;i+=2)printf("%d %d %d\n",s[i],node[i].to,node[i].v); 88 return 0; 89 }
转载于:https://www.cnblogs.com/Kurokey/p/5883027.html
Codeforces Round #372 (Div. 1) B. Complete The Graph相关推荐
- 构造图 Codeforces Round #236 (Div. 2) C. Searching for Graph
题目地址 1 /* 2 题意:要你构造一个有2n+p条边的图,使得,每一个含k个结点子图中,最多有2*k+p条边 3 水得可以啊,每个点向另外的点连通,只要不和自己连,不重边就可以,正好2*n+p就结 ...
- Codeforces Round #579 (Div. 3) F2. Complete the Projects (hard version) dp + 贪心
传送门 文章目录 题意: 思路: 题意: 思路: 排序方式跟easyeasyeasy版本的一样,但是hardhardhard版本是输出最多能选多少,所以我们对b<0b<0b<0的情况 ...
- Codeforces Round #579 (Div. 3) F1. Complete the Projects (easy version) 排序 + 贪心
传送门 文章目录 题意: 思路: 题意: 思路: 比较直观的想法就是对于bi≥0b_i\ge0bi≥0的项目,我们将aia_iai从小到大排序,让后依次加bib_ibi,如果有取不到的,显然就无 ...
- Codeforces Round #715 (Div. 1) C. Complete the MST 补图 + 思维 + 最小生成树
传送门 文章目录 题意: 思路 题意: 给你一张nnn个点mmm个边的图,mmm条边是给定的,要求你给未给定的边赋值一个边权,使得所有边权异或和为000,求所有满足这种情况的图中最小生成树边权和最小的 ...
- Codeforces Round #372 (Div. 2), problem: (B) Complete the Word
水题,每次截取长度为26的字符串,然后直接进行修改就可以 然而本弱渣昨天wa看很久 include<bits/stdc++.h> using namespace std; int n,c; ...
- Codeforces Round #236 (Div. 2) C. Searching for Graph(水构造)
题目大意 我们说一个无向图是 p-interesting 当且仅当这个无向图满足如下条件: 1. 该图恰有 2 * n + p 条边 2. 该图没有自环和重边 3. 该图的任意一个包含 k 个节点的子 ...
- Codeforces Round #179 (Div. 2): D. Greg and Graph(Floyd)
题意: 给你n个点有向图的邻接矩阵,之后再给你n个数,它一定是1到n的全排列,对于第i个点,求出在删掉这个点以及与这个点相邻的所有边之前,当前剩下所有点两两最短路之和,注意删除操作是持久的,也就是最后 ...
- Codeforces Round #715 (Div. 2)
Codeforces Round #715 (Div. 2) 题号 题目 知识点 A Average Height B TMT Document C The Sports Festival 区间dp ...
- Codeforces Round #277 (Div. 2) 题解
Codeforces Round #277 (Div. 2) A. Calculating Function time limit per test 1 second memory limit per ...
最新文章
- 索引贴——移动开发(.Net CF 停止更新)
- python话雷达图-python使用matplotlib绘制雷达图
- python使用什么格式划分语句块-python以什么划分语句块
- 深入浅出Python元编程
- LINUX设备模型BUS,DEVICE,DRIVER
- winform Tab键循序 小发现
- python模块使用_一文让你学会所有的python模块使用
- CodeForces 139C Literature Lesson(模拟)
- MATLAB信号处理之常用信号的表示(2)
- Python中tkinter.filedialog
- 10 倍高清不花!大麦端选座 SVG 渲染
- recyclervie刷新到底部_自定义RecyclerView添加HeaderView,添加FooterView,实现滑动到底部,加载更多...
- CUDA实现QuickSortr排序算法(一)
- 五一期间完成了某市交警系统的一个系统升级迁移项目
- 图片无损放大器有什么软件推荐?这个不要错过
- IDEA 之搭建spring-boot maven报错Project ‘org.springframework.boot:spring-boot-starter-parent:2.2.0.RELEAS
- 手机端通过Es文件浏览器访问windows服务器用File Zilla Sever软件 分享的文件
- 一分钟了解什么是代理ip和api接口
- java计算机毕业设计物流站环境监测系统源码+系统+数据库+lw文档+mybatis+运行部署
- 开发者账号注册的详细流程
热门文章
- android imageview 事件传递,Android 事件传递机制TextView,ImageView等没有默认clickable属性的View单独设置onTouch事件注意事项...
- AcWing 847. 图中点的层次(BFS模板)
- AndroidStudio快捷键大全
- Retrofit的讲解和使用
- python 加干扰线 图片生成_用Python一键生成炫酷九宫格图片,火了朋友圈
- elasticsearch6.0单机配置+centos7.0J+dk1.8
- nginx的源码编译及相关文件配置
- [一句秒懂]小马的单例
- Atitit.struts排除url 的设计and 原理 自定义filter 排除特定url
- 【算法导论】简单哈希表的除法实现