洛谷

bzoj

用了分层图的思想

题意

给一张图,要求你再尽可能的多连边,使得从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的更多相关文章

  1. 洛谷 P3505 [POI2010]TEL-Teleportation

    P3505 [POI2010]TEL-Teleportation 题目描述 King Byteasar is the ruler of the whole solar system that cont ...

  2. Teleportation(tel)

    Teleportation(tel) 题目描述 Zy大帝拥有n个星球,因为距离非常遥远,所以Zy在他所居住的1号星球和他的军事基地霸中所在的2号星球建造了两个传送门,这样从1号星球到2号星球就只需要2 ...

  3. [luogu3505][bzoj2088][POI2010]TEL-Teleportation【分层图】

    题目大意 给出了一个图,然后让你加最多的边,让点\(1\)到\(2\)之间至少要经过5条边 解法 比较清楚,我们可以将这个图看作一个分层图,点\(1\)为第一层,再将\(2\)作为第五层,这样第一层和 ...

  4. POI2010题解

    POI2010题解 我也不知道我为什么就开始刷POI了 有些题目咕掉了所以不完整(我都不知道POI到底有多少题) [BZOJ2079][Poi2010]Guilds (貌似bz跟洛谷上的不是一个题?) ...

  5. 拨打电话tel: 跳转到邮件mailto:(html)

    拨打电话 <a href="tel://0571866000">0571-866000</a> 跳转到邮件 <a href="mailto: ...

  6. 国内固定电话正则验证:'tel': [/0\d{2,3}-\d{7,8}(|([-\u8f6c]{1}\d{1,5}))$/, "请填写有效的电话号码"],

    // 验证字段 $('#info_form').validator({ rules : { checkMobile : function(ele) { return checkMobile(ele); ...

  7. Android网页中tel,sms,mailTo,Intent,Market协议用法总结

     tel:协议---拨打电话 <a href="tel:">调出拨号界面</a> <a href="tel:10086">调 ...

  8. BZOJ 2080: [Poi2010]Railway 双栈排序

    2080: [Poi2010]Railway Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 140  Solved: 35[Submit][Statu ...

  9. 安卓版微信内置浏览器,<a href="tel:电话号码"></a> 这个链接失效,不能跳到拨号界面?

    https://segmentfault.com/q/1010000000318831 在URL最后面加“ #mp.weixin.qq.com ”,应该加其他qq.com的二级域名都行,估计是微信的安 ...

随机推荐

  1. es分页条数限制

    "error": { "root_cause": [ { "type": "query_phase_execution_excep ...

  2. 使用docker搭建selenium grid 分布式环境

    本文章只做docker搭建selenium grid 分布式环境步骤说明,对于selenium grid中的参数.流程.原理等不做说明.selenium grid的详细情况可查看官方文档https:/ ...

  3. 在java 中一种简单方式的声明静态Map常量的方法

    我现在需要在一个类里面放一个HashMap,往里面放一些数据,每次要从数据库中取数据的时候先查找HashMap,看是否已经存在,若存在就直接提取,若不存在就从数据库中抽取数据之后再放到HashMap中 ...

  4. Java课程设计之——爬虫篇

    主要使用的技术 Httplcient Jsoup 多线程 dao模式 网络爬虫简介 网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取 ...

  5. vue组件之间值传递四种方法汇总

    1.父组件获取子组件的数据和方法 $refs 子组件: <template> <div class="header"> <h3>{{ zz }} ...

  6. 今天我们来谈谈绝对定位和相对定位的区别,和需要注意的问题;position:absolute|relative;

    首先position:absolute|relative; 前者是绝对定位,后者是相对定位: position属性的四个值: static,relative,fixed,absolute; 重点重点重 ...

  7. 详解 File类

    在讲解File类之前,本人先要讲解下 路径,因为我们对于文件的操作是离不开路径的: 目录 路径: File类 文件名称过滤器: 路径: 请观看本人博文 -- <详解 绝对路径与 相对路径> ...

  8. 视频+图文 String类干货向总结

    目录 一.字符串的介绍及视频讲解 二.字符串的两种创建方式 方法一:通过new创建 方法二:直接创建 三.字符串的长度获取:length()方法 四.使用 == 和equals()方法比较两个字符串 ...

  9. 【题解】P2024 [NOI2001]食物链 - 数据结构 - 并查集

    P2024 [NOI2001]食物链 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 动物王国中有三类动物 \(A,B ...

  10. ATmega328P定时器详解

    写这篇文章,纯粹是想为博客拉点点击量.在博客园,游客访问好像是不计入阅读量的,而作为一个十八线博主,注册用户的访问应该以搜索引擎为主,博客园首页为次,个位数的粉丝就别谈了. 所以,希望各位从搜索引擎点 ...