[bzoj2088]P3505 [POI2010]TEL-Teleportation
题意
给一张图,要求你再尽可能的多连边,使得从1到2至少要经过5条边
没啥复杂的公式,讲解都在注释里
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<map>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
register int x=0;register int y=1;
register char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
//P3505 [POI2010]TEL-Teleportation https://www.luogu.com.cn/problem/P3505
//bzoj2088 https://darkbzoj.tk/problem/2088
//题目的意思实际上就是,给出一张图,问最多能加几条边,使得 1->2 的最短路径长度,大于等于 5
//用一点分层图的思想
//考虑将图分成 5 层
//一层:点 1
//二层:和 1 相连的点
//五层:点 2
//四层:和 2 相连的点
//三层:剩下的点
//然后如何加边在代码的注释里,大体思路就是先考虑一层内的加边,然后再考虑层与层之间的
//最后再减去原有的边数,至于怎么严格证明这样是最优的并不会...
//type 表示的是所在层的编号
int type[40006];
int x[1000006],y[1000006];
int n,m;
int link[40006];//这个表示的是 3 层中的点与 2,4 哪一层相连,具体看下面的注释
inline void swap(int &x,int &y){x^=y;y^=x;x^=y;}
int main(){
n=read();m=read();
for(reg int i=3;i<=n;i++) type[i]=3;
type[1]=1;type[2]=5;
int edgenum_2=0,edgenum_3=0,edgenum_4=0;//两个端点均为某层的边的个数
int edgenum_23=0,edgenum_34=0;//两层之间的边数
for(reg int i=1;i<=m;i++){//先处理出各个点都在哪一层
x[i]=read();y[i]=read();
if(x[i]>y[i]) swap(x[i],y[i]);
if(x[i]==1) type[y[i]]=2;
else if(x[i]==2) type[y[i]]=4;
}
for(reg int i=1;i<=m;i++){//处理边数
if(type[x[i]]==2&&type[y[i]]==2) edgenum_2++;
else if(type[x[i]]==3&&type[y[i]]==3) edgenum_3++;
else if(type[x[i]]==4&&type[y[i]]==4) edgenum_4++;
else if((type[x[i]]==2&&type[y[i]]==3)||(type[x[i]]==3&&type[y[i]]==2)) edgenum_23++;
else if((type[x[i]]==4&&type[y[i]]==3)||(type[x[i]]==3&&type[y[i]]==4)) edgenum_34++;
}
int vertex_2=0,vertex_3=0,vertex_4=0;//处理各个层的点的个数
for(reg int i=1;i<=n;i++){
if(type[i]==2) vertex_2++;
else if(type[i]==3) vertex_3++;
else if(type[i]==4) vertex_4++;
}
int ans=0;
//先处理每层内部连边
ans+=vertex_2*(vertex_2-1)/2-edgenum_2;
ans+=vertex_4*(vertex_4-1)/2-edgenum_4;//2,4 层内的点能随便互相连,肯定不会使路径小于 5
//3 层内的点,我们要保证从 2 层走到 3 层后,不能立刻走到 4 层,否则就会出现长度为 4 的路径
//也就是说要有一步是从 3 层的点起步,然后终点也是 3 层的点
//那么,如果和 2 层的某个点相连,就不能和与 4 层的任何点相连,反之,和 4 相连不和 2 相连
//题目规定有解,所以并不会有点同时与 2,4 相连(在原有的边的情况下)
//那么我们可以考虑先处理出在第 3 层中,哪些点与 2 层中的点相连,哪些和 4 中的点相连
for(reg int i=1;i<=m;i++){
if(type[x[i]]==3){
if(type[y[i]]==4) link[x[i]]=4;
else if(type[y[i]]==2) link[x[i]]=2;
}
if(type[y[i]]==3){
if(type[x[i]]==4) link[y[i]]=4;
else if(type[x[i]]==2) link[y[i]]=2;
}
}
int link_2=0,link_4=0,link_no=0;//分别是:在第三层中,与第二层的点相连的点数,与第四层的点相连的点数,不与二或四层的点相连的点数
for(reg int i=1;i<=n;i++)if(type[i]==3){
if(link[i]==2) link_2++;
else if(link[i]==4) link_4++;
else link_no++;
}
ans+=link_no*(link_no-1)/2;//不与 2,4 相连的点随便连
//下面两行就是前面讲的,如果一个点和 2 层相连,那么它可以再与其余的在第三层,并且与 2 层相连的点相连,也可以和不与 2,4 层相连的点相连
//和 4 层相连的点也是同理
//这部分自己拿样例画画图比较好
ans+=link_2*(link_2-1)/2+link_2*link_no;
ans+=link_4*(link_4-1)/2+link_4*link_no;
ans+=link_2*link_4;//和 2 层相连的也可以与和 4 层相连的点随便连
ans-=edgenum_3;//去掉原有的,两个端点都在第 3 层的边数
/********************************************************************/
//下面是不同层之间的连边
//显然,不能跨过一层连边,那样肯定有小于 5 的路径,只能在相邻的层之间连
//1,2 层和 4,5 层肯定不会再有能连的边了
//对于第 3 层:
ans+=link_2*vertex_2-edgenum_23;//和 2 层相连接的点,可以和其它的 2 层的点都连起来,然后再减去 2,3 层之间的边去重
ans+=link_4*vertex_4-edgenum_34;//和 4 层相连的,同理
ans+=link_no*std::max(vertex_2,vertex_4);
//解释上一行:对于不和 2 或 4 层相连的点,只能和 2 或 4 层其中一层的所有点相连,为例最大化边数,肯定是都和 2,4 中点多的一层中的所有点链接
std::printf("%d",ans);
return 0;
}
[bzoj2088]P3505 [POI2010]TEL-Teleportation的更多相关文章
- 洛谷 P3505 [POI2010]TEL-Teleportation
P3505 [POI2010]TEL-Teleportation 题目描述 King Byteasar is the ruler of the whole solar system that cont ...
- Teleportation(tel)
Teleportation(tel) 题目描述 Zy大帝拥有n个星球,因为距离非常遥远,所以Zy在他所居住的1号星球和他的军事基地霸中所在的2号星球建造了两个传送门,这样从1号星球到2号星球就只需要2 ...
- [luogu3505][bzoj2088][POI2010]TEL-Teleportation【分层图】
题目大意 给出了一个图,然后让你加最多的边,让点\(1\)到\(2\)之间至少要经过5条边 解法 比较清楚,我们可以将这个图看作一个分层图,点\(1\)为第一层,再将\(2\)作为第五层,这样第一层和 ...
- POI2010题解
POI2010题解 我也不知道我为什么就开始刷POI了 有些题目咕掉了所以不完整(我都不知道POI到底有多少题) [BZOJ2079][Poi2010]Guilds (貌似bz跟洛谷上的不是一个题?) ...
- 拨打电话tel: 跳转到邮件mailto:(html)
拨打电话 <a href="tel://0571866000">0571-866000</a> 跳转到邮件 <a href="mailto: ...
- 国内固定电话正则验证:'tel': [/0\d{2,3}-\d{7,8}(|([-\u8f6c]{1}\d{1,5}))$/, "请填写有效的电话号码"],
// 验证字段 $('#info_form').validator({ rules : { checkMobile : function(ele) { return checkMobile(ele); ...
- Android网页中tel,sms,mailTo,Intent,Market协议用法总结
tel:协议---拨打电话 <a href="tel:">调出拨号界面</a> <a href="tel:10086">调 ...
- BZOJ 2080: [Poi2010]Railway 双栈排序
2080: [Poi2010]Railway Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 140 Solved: 35[Submit][Statu ...
- 安卓版微信内置浏览器,<a href="tel:电话号码"></a> 这个链接失效,不能跳到拨号界面?
https://segmentfault.com/q/1010000000318831 在URL最后面加“ #mp.weixin.qq.com ”,应该加其他qq.com的二级域名都行,估计是微信的安 ...
随机推荐
- 2017蓝桥杯日期问题(C++B组)
标题:日期问题小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月31日.令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的, ...
- asap异步执行实现原理
目录 为什么分析asap asap概述 asap源码解析-Node版 参考 1.为什么分析asap 在之前的文章 async和await是如何实现异步编程? 中的浅谈Promise如何实现异步执行小节 ...
- django中写分页
1.引用函数import from django.core.paginator import Paginator 2.分页 page_obj = Paginator(Article.objects.a ...
- 多数据源系统接入mybatis-plus, 实现动态数据源、动态事务。
目录: 实现思想 导入依赖.配置说明 代码实现 问题总结 一.实现思想 接手一个旧系统,SpringBoot 使用的是纯粹的 mybatis ,既没有使用规范的代码生成器,也没有使用 JPA 或者 m ...
- 34 io流-- 打印流和对象流
概述 io流分为字符流和字节流,具体分类相见下图 字符流:char 一些基本文本的数据传输 字节流:byte 图片.视频等用文本查看器查看不了的文件都是二进制文件,只能用字节流传输,使用字符流cp的看 ...
- C语言小练习之学生信息管理系统
C语言小练习之学生信息管理系统 main.c文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 2 ...
- 统计子串数量,Python基础
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:陈YL PS:如有需要Python学习资料的小伙伴可以加点击下方链接自 ...
- bytectf2019 boring_code的知识学习&&无参数函数执行&&上海市大学生CTF_boring_code+
参赛感悟 第三次还是第二次参加这种CTF大赛了,感悟和学习也是蛮多的,越发感觉跟大佬的差距明显,但是还是要努力啊,都大三了,也希望出点成绩.比赛中一道WEB都没做出来,唯一有点思路的只有EZCMS,通 ...
- 【高频 Redis 面试题】Redis 事务是否具备原子性?
一.Redis 事务的实现原理 一个事务从开始到结束通常会经历以下三个阶段: 1.事务开始 客户端发送 MULTI 命令,服务器执行 MULTI 命令逻辑. 服务器会在客户端状态(redisClien ...
- 加不加 synchronized 有什么区别?
今天一起来认识认识 synchronized 这个一面试就会被提到的关键字.这一篇不会讲太多理论,主要先熟悉熟悉一下最简单的用法.只讨论一个问题:方法没用 synchronized 和用了 synch ...