Codeforces 164 D Minimum Diameter
做题感悟:越来越感觉CF的题非常好,非常有深度。
解题思路:
这题须要注意 k 的大小。由于 k 仅仅有 30 个,终于形成的点的直径一定是某个确定的值,所以我们能够枚举这个值。然后把大于这个值的边都取消(删除不大于k 个点),这样不断二分剩下点的最小直径。每次二分的时候推断是否合法。
这里推断是否合法非常重要。由于这须要用dfs去枚举,一不小心就会超时。dfs 在枚举删除每一个点的时候主要枚举两个方面。(1)假设想删除与当前点相连的全部边,能够选择删除全部与之相连的点 (2)能够单独删除此点,然后与之相连的全部边都删除了。这里有一个剪枝:假设以下删除所达到的状态不如上面的优就不继续深搜下去了。由于到达当前点所形成的状态是一样的(都把与1
~ x 节点相连的边都删除了),就看剩下能够删除点多的必然优。
代码:
- #include<iostream>
- #include<sstream>
- #include<map>
- #include<cmath>
- #include<fstream>
- #include<queue>
- #include<vector>
- #include<sstream>
- #include<cstring>
- #include<cstdio>
- #include<stack>
- #include<bitset>
- #include<ctime>
- #include<string>
- #include<cctype>
- #include<iomanip>
- #include<algorithm>
- using namespace std ;
- #define INT __int64
- #define L(x) (x * 2)
- #define R(x) (x * 2 + 1)
- const int INF = 0x3f3f3f3f ;
- const double esp = 0.0000000001 ;
- const double PI = acos(-1.0) ;
- const int mod = 1e9 + 7 ;
- const int MY = 1400 + 5 ;
- const int MX = 1010 + 5 ;
- int num ,n ,k ;
- vector<int>G[MX] ;
- int d[MX*MX] ,g[MX][MX] ,vis[MX] ;
- struct node
- {
- int x ,y ;
- }P[MX] ;
- bool dfs(int cnt ,int m) // cnt 代表编号 。m 代表删除的边数
- {
- if(cnt > n) return true ;
- if(vis[cnt]) return dfs(cnt + 1 ,m) ;
- for(int i = 0 ;i < (int)G[cnt].size() ; ++i)
- {
- m += !vis[G[cnt][i]] ;
- vis[G[cnt][i]]++ ;
- }
- if(m <= k && dfs(cnt + 1 ,m))
- return true ;
- int temp = m ;
- for(int i = 0 ;i < (int)G[cnt].size() ; ++i)
- {
- vis[G[cnt][i]]-- ;
- m -= !vis[G[cnt][i]] ;
- }
- if(G[cnt].size() != 1)
- {
- vis[cnt]++ ;
- if(m + 1 <= k && m + 1 < temp && dfs(cnt+1 ,m+1))
- return true ;
- vis[cnt]-- ;
- }
- return false ;
- }
- bool judge(int dist)
- {
- memset(vis ,false ,sizeof(vis)) ;
- for(int i = 1 ;i <= n ; ++i)
- G[i].clear() ;
- for(int i = 1 ;i < n ; ++i)
- for(int j = i+1 ;j <= n ; ++j)
- if(g[i][j] > dist)
- {
- G[i].push_back(j) ;
- G[j].push_back(i) ;
- }
- return dfs(1 ,0) ;
- }
- int binary_search(int le ,int rt) //
- {
- int mid ;
- while(le < rt)
- {
- mid = (le + rt)>>1 ;
- if(judge(d[mid])) rt = mid ;
- else le = mid + 1 ;
- }
- return le ;
- }
- int main()
- {
- //freopen("input.txt" ,"r" ,stdin) ;
- while(~scanf("%d%d" ,&n ,&k))
- {
- num = 0 ; d[0] = 0 ;
- for(int i = 1 ;i <= n ; ++i)
- scanf("%d%d" ,&P[i].x ,&P[i].y) ;
- for(int i = 1 ;i < n ; ++i)
- for(int j = i+1 ;j <= n ; ++j)
- d[++num] = g[i][j] = (P[i].x-P[j].x)*(P[i].x-P[j].x) + (P[i].y - P[j].y)*(P[i].y-P[j].y) ;
- sort(d ,d + num + 1) ;
- num = unique(d ,d+num+1) - d - 1 ;
- int mx = binary_search(0 ,num) ; // 二分查找最小直径
- judge(d[mx]) ;
- bool first = false ;
- for(int i = n ;i >= 1 ; --i)
- if(vis[i])
- {
- if(first) putchar(' ') ;
- printf("%d" ,i) ;
- k-- ;
- first = true ;
- }
- for(int i = n ;i >= 1 && k > 0 ; --i)
- if(!vis[i])
- {
- if(first) putchar(' ') ;
- printf("%d" ,i) ;
- k-- ;
- first = true ;
- }
- cout<<endl ;
- }
- return 0 ;
- }
Codeforces 164 D Minimum Diameter的更多相关文章
- 【Codeforces 1086B】Minimum Diameter Tree
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 统计叶子节点个数m 把每条和叶子节点相邻的边权设置成s/cnt就可以了 这样答案就是2*s/m(直径最后肯定是从一个叶子节点开始,到另外一个叶 ...
- D. Minimum Diameter Tree 思维+猜结论
D. Minimum Diameter Tree 思维+猜结论 题意 给出一颗树 和一个值v 把该值任意分配到任意边上 使得\(\sum\limits_{i,j}p_{ij}=v\) 使得 这颗树任意 ...
- CodeForces 164 B. Ancient Berland Hieroglyphs 单调队列
B. Ancient Berland Hieroglyphs 题目连接: http://codeforces.com/problemset/problem/164/B Descriptionww.co ...
- codeforces ~ 1009 B Minimum Ternary String(超级恶心的思维题
http://codeforces.com/problemset/problem/1009/B B. Minimum Ternary String time limit per test 1 seco ...
- Codeforces 893F - Subtree Minimum Query
893F - Subtree Minimum Query 题意 给出一棵树,每次询问 \(x\) \(k\),求以 \(x\) 为根结点的子树中的结点到结点 \(x\) 的距离小于等于 \(k\) 的 ...
- Codeforces 279D The Minimum Number of Variables 状压dp
The Minimum Number of Variables 我们定义dp[ i ][ mask ]表示是否存在 处理完前 i 个a, b中存者 a存在的状态是mask 的情况. 然后用sosdp处 ...
- Codeforces 1082 D. Maximum Diameter Graph-树的直径-最长链-构造题 (Educational Codeforces Round 55 (Rated for Div. 2))
D. Maximum Diameter Graph time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- Codeforces 805D/804B - Minimum number of steps
传送门:http://codeforces.com/contest/805/problem/D 对于一个由‘a’.‘b’组成的字符串,有如下操作:将字符串中的一个子串“ab”替换成“bba”.当字符串 ...
- 【codeforces 805D】Minimum number of steps
[题目链接]:http://codeforces.com/contest/805/problem/D [题意] 给你一个字符串; 里面只包括a和b; 让你把里面的"ab"子串全都去 ...
随机推荐
- jquery开发之代码风格
1,链式操作风格. (1) 对于同一个对象不超过三个操作的.可直接写成一行.代码例如以下: $("li").show().unbind("click"); (2 ...
- ASMlib操作系统包安装与配置asm disk磁盘
1.加入6块硬盘,每块100g.不管是热加还是冷加.不管是加硬盘,用san存储划lun,或者再加上多路径,都是能够这么做的. 在操作系统层,能识别这种lun.以下的sdb就是一个刚划分的300g的lu ...
- jni传递对象中包含arraylist对象。
相信在使用jni的过程中,总是要传递各种各样的类型,在这其中,我也碰到了一些问题. 简单的传一些内容,相信在网上一搜一大把. 所以我们就来说说.传递对象中包含arraylist吧. 在这里先给大家一个 ...
- SVN冲突的解决过程
此文教程只是个人记录使用,不建议当教程!(估计新手也看得懵) 改完之后Ctrl+s保存就好.
- 那些不兼容 IE11的网站(持续更新)
此博文用于收集不兼容 IE11 的网站,持续更新,请网站开发者自己认领: 兼容性引起的功能缺陷: v.qq.com (提示未安装 Flash 播放器,这问题我反馈几百年了,还没修复) tv.sohu. ...
- pyton写购物车
pyton写购物车 基本要求: 用户输入工资,然后打印购物菜单用户可以不断的购买商品,直到余额不够为止退出时打印用户已购买的商品和剩余金额.. 1.这个程序功能不完整,bug很多,练手之作. good ...
- Android 在Android手机上获取其他应用的包名及版本号
获取Android手机上其他应用的包名及版本号方法有很多,可以通过AAPT从APK包中直接获取,也可以通过代码在手机上获取.显然,对于产品或者用户来说要获取这些信息,在手机上获取更为简便. 下面我们来 ...
- Android项目实战(五十七):Glide 高斯模糊效果
核心需要高斯模糊的库 compile 'jp.wasabeef:glide-transformations:2.0.1' 针对于3.7的版本 使用方法为: //加载背景, Glide.with(Mus ...
- Python3基础笔记---re模块
参考博客: Py西游攻关之模块 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列 ...
- SSD-tensorflow-2 制作自己的数据集
VOC2007数据集格式: VOC2007详细介绍在这里,提供给大家有兴趣作了解.而制作自己的数据集只需用到前三个文件夹,所以请事先建好这三个文件夹放入同一文件夹内,同时ImageSets文件夹内包含 ...