CFGym 101490E 题解
一、题目链接
http://codeforces.com/gym/101490
二、题面
三、题意
给你一个图,n个点,m条边,一个x,从顶点1走到顶点n。假设从顶点1走到顶点n的最短路为d,x代表你可以选择的路径的长度范围:[d, d * (1 + x%)]。让你求出在所有长度在此区间内的路径,路径上最大的边的最小值。如图所示:
从顶点1到顶点9的最短距离为16。所以,可选的路径范围是:[16, 18.4]。可以发现,1->4->7->8->9这条路径的长度为18,是在此区间内的,而且这条路径上的边最大值为5。而另一条有效路径是1->9,边最大值是16。所以,答案是5。
四、思路
先跑一遍最短路算法,得到从顶点1到顶点n的最短路径。然后,二分最大边权,把大于枚举值mid的边全部删掉,再跑最短路,如果从1到n的最短路在[d, d * (1 + x%)]范围内,说明枚举的mid是有效的。最后输出枚举的最小的最大值即可。
删边怎么删呢?千万别用set或者vector之类的容器去模拟删除,这样复杂度会大很多。快速的方法是:使用两个图,一个是原图,另一个是二分最大边权的图,每次枚举一个mid时,都用原图来筛选,把大于mid的边直接过滤掉就OK了。
为什么这样是正确的呢?因为答案是满足单调性的。(现在我只能这么写。有些感觉上的东西实在是表达不出来呀。)
五、源代码
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int, LL> PLL;//first:邻接点,second:和邻接点之间的边权。 ; vector<PLL> g[][MAXN]; int n, m, x; double minl, maxl; typedef pair<LL, int> P;//跑dijstra算法必备的。 LL d[MAXN]; LL djst(int s, int which) { priority_queue<P, vector<P>, greater<P> > que; memset(d, 0x3f, sizeof(d)); d[s] = ; que.push(P(, s)); while(!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if(d[v] < p.first)continue; , sz = g[which][v].size(); i < sz; ++i) { PLL pll = g[which][v][i]; if(d[pll.first] > d[v] + pll.second) { d[pll.first] = d[v] + pll.second; que.push(P(d[pll.first], pll.first)); } } } return d[n]; } bool test(LL mid){ ;i < MAXN;++i)g[][i].clear(); ;i <= n;++i){ , sz = g[][i].size();j < sz;++j){ PLL pll = g[][i][j]; ][i].push_back(pll); } } LL dis = djst(, ); double ddis = (double)dis; if(ddis > minl && ddis < maxl)return true; || fabs(ddis - maxl) < 1e-)return true; return false; } int main() { #ifndef ONLINE_JUDGE freopen("Einput.txt", "r", stdin); #endif // ONLINE_JUDGE int a, b; LL c; while(~scanf("%d%d%d", &n, &m, &x)) { ; i < MAXN; ++i)g[][i].clear(); ; i <= m; ++i) { scanf("%d%d%lld", &a, &b, &c); g[][a].push_back(make_pair(b, c)); g[][b].push_back(make_pair(a, c)); } minl = (, ); maxl = minl * (1.0 + x * 1.0 / 100.0); LL low = -, high = 1LL << , mid; ){ mid = (low + high) / ; if(test(mid))high = mid; else low = mid; } printf("%lld\n", high); } ; }
经验:long long类型的数值做数组下标也是没问题的。这样,在需要使用long long数据类型的题目中,通通使用long long数据类型,包括for循环,这样可以省去各种麻烦的类型转换操作。尤其是使用C/C++语言,编译器没有自动类型转换的情况下。
CFGym 101490E 题解的更多相关文章
- CFGym 101490J 题解
一.题目链接 http://codeforces.com/gym/101490 二.题面 三.题意 给你n个点,代表学生所在位置,n个点,代表老师所在位置.每个学生分配一个老师.让你找出一个最小的学生 ...
- CFGym 101161I 题解
一.题目链接 http://codeforces.com/gym/101161/problem/I 二.题意 给定一棵树,一个初始的省会城市,若干个询问,0表示修改省会城市,1表示查询去省会必须经过指 ...
- CFGym 100198G 题解
一.题目链接 http://codeforces.com/gym/100198/problem/G 二.题意 看样例就能明白,写表达式解析器. 三 .思路 一看这题目,立马就会想到“后缀表达式”,考虑 ...
- CFGym 101194L 题解
一.题目链接 http://codeforces.com/gym/101194/problem/L 二.题意 有4个队伍,要打6场比赛(刚好每两个队伍都能相互比一次),若A和B比赛有3种结果: A赢B ...
- CFGym 101194D 题解
一.题目链接 http://codeforces.com/gym/101194/problem/D 二.题意 给定一个数字n和一个数字k,一个n个整数的序列,让你在里面找尽可能多的长度为k的符合“要求 ...
- CFGym 101505I 题解
一.题目链接 http://codeforces.com/gym/101505 二.题意 这题其实主要就是题意,理解题意后,就是水题了.我想了下,主要原因就是这几点: 1.题意太过英文化,很多句子不能 ...
- CFGym 100211J 题解
一.题目 二.题意 给定一个字母表(最多也就是英文小写字母的前10个字母),一个交换表,两个字符串,判断字符串A能否通过交换表的交换方式变成字符串B. 三.思路 1.一开始,比赛时,我半模拟半记忆化地 ...
- [CF-GYM]Abu Tahun Mod problem题解
前言 这道题比较简单,但我还是想了好一会 题意简述 Abu Tahun很喜欢回文. 一个数组若是回文的,那么它从前往后读和从后往前读都是一样的,比如数组\(\left\{1\right\},\left ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
随机推荐
- UVa 10534 波浪子序列(快速求LIS)
https://vjudge.net/problem/UVA-10534 题意:给定一个长度为n的整数序列,求一个最长子序列(不一定连续),使得该序列的长度为2k+1,前k+1个数严格递增,后k+1个 ...
- Symmetric Tree,对称树
问题描述: Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). ...
- 2016"百度之星" - 初赛(Astar Round2A) 1006 Gym Class 拓扑排序
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem ...
- redis高可用 - Master&Slave
Master&Slave也就是我们所说的主从复制,即主机数据更新后根据配置和策略,自动同步到备机的机制.其中Master以写为主,Slave以读为主. Master&Slave的作用主 ...
- H5 canvas控制坦克移动
接着上一篇(http://www.cnblogs.com/zhouhuan/p/H5_tankgame.html),这一篇研究一下怎么响应玩家的操作让坦克进行相应的移动. 1. 了解keydown ...
- C#用大石头Xcode做数据底层注意事项
1.记得添加XCode.dll 和NewLife.Core.dll 2.记得把程序的框架改为 .net Framework4
- UVA-11988 Broken Keyboard (a.k.a. Beiju Text) (链表 或 递归)
题目大意:将一个字符串改变顺序后输出.遇到“[”就将后面内容拿到最前面输出,遇到“]”就将后面的内容拿到最后面输出. 题目分析:用nxt[i]数组表示i后面的字符的下标,实际上就是以字符i为头建立链表 ...
- 3321 Apple Tree 树状数组
LIANJIE:http://poj.org/problem?id=3321 给你一个多叉树,每个叉和叶子节点有一颗苹果.然后给你两个操作,一个是给你C清除某节点上的苹果或者添加(此节点上有苹果则清除 ...
- [转载]java调用本地dos命令
在社区看到java调用本地dos命令的代码,特贴出来 String command = "ipconfig"; Runtime run = Runtime.getRuntime() ...
- 第一个openGL程序
一.工具的安装 因为要写C++程序,为了便捷,这里我安装的Visual Studio: 免费使用90天!安装好了之后,我们要为我们的开发安装相应的工具集: 因为我是要在windows上跑的,所以选择如 ...