Codeforces715 B. Complete The Graph
传送门:>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的更多相关文章
- 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 ...
- CF715B. Complete The Graph
CF715B. Complete The Graph 题意: 给一张 n 个点,m 条边的无向图,要求设定一些边的边权 使得所有边权都是正整数,最终 S 到 T 的最短路为 L 1 ≤ n ≤ 100 ...
- 【Codeforces】716D Complete The Graph
D. Complete The Graph time limit per test: 4 seconds memory limit per test: 256 megabytes input: sta ...
- CodeForces 715B Complete The Graph 特殊的dijkstra
Complete The Graph 题解: 比较特殊的dij的题目. dis[x][y] 代表的是用了x条特殊边, y点的距离是多少. 然后我们通过dij更新dis数组. 然后在跑的时候,把特殊边都 ...
- 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 ...
- Codeforces 715B. Complete The Graph 最短路,Dijkstra,构造
原文链接https://www.cnblogs.com/zhouzhendong/p/CF715B.html 题解 接下来说的“边”都指代“边权未知的边”. 将所有边都设为 L+1,如果dis(S,T ...
- Codeforces Round #372 (Div. 1) B. Complete The Graph (枚举+最短路)
题目就是给你一个图,图中部分边没有赋权值,要求你把无权的边赋值,使得s->t的最短路为l. 卡了几周的题了,最后还是经群主大大指点……做出来的…… 思路就是跑最短路,然后改权值为最短路和L的差值 ...
- Codeforces Round #372 (Div. 1) B. Complete The Graph
题目链接:传送门 题目大意:给你一副无向图,边有权值,初始权值>=0,若权值==0,则需要把它变为一个正整数(不超过1e18),现在问你有没有一种方法, 使图中的边权值都变为正整数的时候,从 S ...
- 715B Complete The Graph
传送门 题目大意 给出一个图,一些边带权,另一些边等待你赋权(最小赋为1).请你找到一种赋权方式,使得 s 到 t 的最短路为 L n ≤ 1e3 ,m ≤ 1e4 ,L ≤ 1e9 分析 二分所有边 ...
随机推荐
- 语法设计——基于LL(1)文法的预测分析表法
实验二.语法设计--基于LL(1)文法的预测分析表法 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 ...
- Django signals 信号作用及用法说明
参考:https://docs.djangoproject.com/en/1.11/ref/signals/ 1.Model signals django.db.models.signales 作用于 ...
- 2017百度软研(C++)
问了很多,不过很多也都没有问到,感觉有点偏,很深入的东西,越问越虚.第一次实习面试从百度开始,也从百度结束吧.看得见的差距,不想将就,所以还是拿最后一次机会去尝试.win or go home, 所以 ...
- PHP的内存回收(GC)
php官方对gc的介绍:http://php.net/manual/zh/features.gc.php
- CentOS搭建OpenVPN以及WIN&Android&iOS的安装连接
OpenVPNhttp://info.swufe.edu.cn/vpn/openvpn/#2 苹果.安卓智能手机openvpn的设置_百度经验https://jingyan.baidu.com/art ...
- java不同的包下相同的类名的问题与解决办法
Java中的类以包进行分类组织,当程序中需要用到某个包下的类时,可以以该类的全限定名进行引用.这样,不同的包中的类就可以同名,不会产生混淆. 但是这样就可能导致引用的时候会产生一些问题. 第一个问题, ...
- Laravel 门面实例教程 —— 创建自定义 Facades 类
我们首先创建一个需要绑定到服务容器的Test类: <?php namespace App\Facades; class Test { public function doSomething() ...
- mysql实现首字母从A-Z排序
1.常规排序ASC DESC ASC 正序 DESC倒叙 -- 此处不用多讲 2.自定义排序 自定义排序是根据自己想要的特定字符串(数字)顺序进行排序.主要是使用函数 FIELD(str,str1,s ...
- Spring-Boot Banner
下载Spring-Boot源码,目录结构spring-boot-2.1.0.M2\spring-boot-2.1.0.M2\spring-boot-project\spring-boot\src\ma ...
- Hbase API