bitset玄学完美优化复杂度?

题目描述

参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里。而食堂门前施工虽然也截断了原来通向计算中心的路,却没有使路程增加,因为可以找到同样长度的路作替代。其实,问题的关键在于,路截断的地方是交通要点。

同样的情况也出现在城市间的交通中。某些城市如果出了问题,可能会引起其他很多城市的交通不便。另一些城市则影响不到别的城市的交通。jsoi冬令营的同学发现这是一个有趣的问题,于是决定研究这个问题。

他们认为这样的城市是重要的:如果一个城市c被破坏后,存在两个不同的城市a和b(a, b均不等于c),a到b的最短距离增长了(或不通),则城市c是重要的。

jsoi冬令营的同学面对着一张教练组交给他们的城市间交通图,他们希望能找出所有重要的城市。现在就请你来解决这个问题。

输入输出格式

输入格式:

第一行两个整数N,M,N为城市数,M为道路数。

接下来M行,每行三个整数,表示两个城市之间的无向边,以及之间的路的长度。

输出格式:

一行,按递增次序输出若干的数,表示重要的城市。

如果没有点的话需要输出一行

“No important cities.”

去掉引号。

输入输出样例

输入样例#1:

4 4
1 2 1
2 3 1
4 1 2
4 3 2

输出样例#1:

2

说明

30%的数据:$N\le 20$;

60%的数据:$N\le 100$;

100%的数据:$N\le 200,M\le \frac{N\times (N-1)}{2},0<c\le 10000$。$c$即路的长度。

保证不出现重边和自环

感谢@赵昕鹏 和@qq2477259579 提供程序

题解:

    因为Floyd是一种玄学DP思想,所以它的状态更新来源有很多,在这个题里需要整理出它的阶段性与转移,看上去十分麻烦。而我们如果把Floyd当作最短路算法中的松弛,就是相当于在把两段最短路拼接在一起,拥有它们合在一起的性质。

重要城市

    重要城市就是如果这个点被删掉,那么最短路的长度就会改变。因此这个点一定在最短路上。而当两点间的最短路有多条时,它们上的点不一定都是重要城市,经过分析我们可以这样理解:设$(u,v)$间最短路条数为$k$,重要城市为$p$,那么这$k$条最短路一定都经过点$p$。用反例来说明,就是如果不是$k$条最短路都经过点$p$,那么去掉点$p$,还有剩下的最短路可以走,则不合法。

    因此我们可以开一个三维数组$im[i][j][k]$表示k在$latex i,j$的几条最短路上。而我们用floyd做最短路计数也比较方便,一旦$k$所在的最短路数量与$(i,j)$间的最短路数量相同,那么$k$就一定是一个重要城市,判断条件为$im[i][j][k]==cnt[i][j]\Rightarrow k$是重要城市。

    在上图中,1→8最短路计数为3,其中除了起点和终点,被经过了3次的点的点有2和7,因此它们是这条路径上的重要城市。

    因为floyd的时间复杂度为$O(N^3)$,而每次更新还要循环一个$N$,因此总时间复杂度为$O(N^4)$。

bitset优化

    我们在上面提到,状态合并/更新需要额外枚举一个$O(N)$,我们可不可以把这个$N$省掉,或者说优化一点呢?

    这时可以考虑bitset,bitset可以使常数优化32倍,这个题的$latex N$规模才200,优化一个32就快把一个$N$变成一个$\log N$了,这个题的数据规模还是可以承受的。不过bitset存的是二进制啊,可是上面提到的数组存的是计数啊。

    我们可以换一个方式想想,如果这两个点之间已经找到了4条最短路,其中有3条经过点$p$,那此时$p$已经不合法了,就直接把它置为0,以后尽管所有路径都经过$p$,它也不可能是关键城市。

    因此bitset中im[i][j][k]里面存的是,现有状态下,k是不是i到j最短路上的关键城市。当更新(松弛)最短路时,关键城市是两段最短路上的关键城市之并集;而更新最短路计数,也就是找到了一条新的最短路时,如上图,就要取交集,因为一个城市只有在两点间任何一条最短路上都存在,才能作为这两点间的关键城市。而交集并集在位运算中就是and(&)和or(|),而点集有200,普通的位运算完成不了,就让bitset来做。

    在一开始初始化时,把两个连接在一起的点上的关键城市设为两个端点,在floyd“松弛”最短路时,直接把两段最短路的关键城市“拼起来”,就是新的最短路上的关键城市。最后判断用$O(N^3)$遍历,看一个点是否为某两个点之间的关键城市,不过要注意不能与这两个点重合,因为为了方便,一开始我们把起点和终点也定为关键城市(符合关键城市的一般定义)。

    因此这道题的总复杂度为$O(\frac{N^4}{32}+N^3)$

Code:

#include<cstdio>
#include<cstring>
#include<bitset>
using std::bitset;
bitset<210> im[210][210];
int f[210][210];
int is[210];
int main()
{
memset(f,0x3f,sizeof(f));
int u,v,n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
f[i][i]=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
scanf("%d",&f[u][v]);
f[v][u]=f[u][v];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
im[i][j][i]=1;//初始化设两端为重要城市
im[i][j][j]=1;
} for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(f[i][k]+f[k][j]==f[i][j])
im[i][j]&=(im[i][k]|im[k][j]);//当更新计数时取交集
else if(f[i][k]+f[k][j]<f[i][j])//当更新最短路时直接赋值为两段的并集
{
f[i][j]=f[i][k]+f[k][j];
im[i][j]=im[i][k]|im[k][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
if(k!=i&&k!=j)//注意特判
if(im[i][j][k])
is[k]=1;
int flag=0;
for(int i=1;i<=n;i++)
if(is[i])
{
flag=1;
printf("%d ",i);
}
if(!flag)//注意判断无解
puts("No important cities.");
return 0;
}

  

【floyd】【bitset】洛谷 P1841 [JSOI2007]重要的城市 题解的更多相关文章

  1. 洛谷 P1841 [JSOI2007]重要的城市 解题报告

    P1841 [JSOI2007]重要的城市 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向 ...

  2. 最短路【洛谷P1841】 [JSOI2007]重要的城市

    P1841 [JSOI2007]重要的城市 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向 ...

  3. 洛谷 P4053 [JSOI2007]建筑抢修

    传送门 思路 首先题意比较容易明白: n个建筑需要修复,只能同时修一个建筑,每个建筑修复需要t1时间,且必须在t2时间前修完,否则此建筑报废 问最多能修好多少个建筑 如果一个建筑在规定时间内没有修好的 ...

  4. 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)

    洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...

  5. 洛谷P1854 花店橱窗布置 分析+题解代码

    洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...

  6. HAOI2006 (洛谷P2341)受欢迎的牛 题解

    HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...

  7. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

  8. 洛谷P1972 [SDOI2009]HH的项链 题解

    [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...

  9. 洛谷 p1352 没有上司的舞会 题解

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

随机推荐

  1. Linux日志文件分析

    ---恢复内容开始--- 日志保存位置 默认 var/log目录下 主要日志文件 内核及公共消息日志:message 计划任务日志:cron 系统殷桃日志:demsg 邮件系统日志:maillog 用 ...

  2. c语言实战 BJT时间转化位UTC时间

    题目是这样的: 题目内容: UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8.现在,你的程序要读入一个整数,表示BJT的时和分.整数的个位和十位表示分,百位和千位表示小时.如果小时小 ...

  3. Luogu 3899 [湖南集训]谈笑风生

    BZOJ 3653权限题. 这题方法很多,但我会的不多…… 给定了$a$,我们考虑讨论$b$的位置: 1.$b$在$a$到根的链上,那么这样子$a$的子树中的每一个结点(除了$a$之外)都是可以成为$ ...

  4. select样式调整

    如果select样式如下图:是因为添加了 border-color:#adb7d6; border-width:1px; 样式 删除上面两个样式属性,效果如下图:

  5. cbv+resful+APIView源码分析

    CBV源码分析 1概念:什么是cbv和fbv 已经什么是API class bass View ---基于类的视图 function bass View ---基于函数的视图 API(Applicat ...

  6. C/C++预处理指令常见的预处理指令

    C/C++预处理指令常见的预处理指令如下: #空指令,无任何效果 #include包含一个源代码文件 #define定义宏 #undef取消已定义的宏 #if如果给定条件为真,则编译下面代码 #ifd ...

  7. css总结9:内边距(padding)和外边距(margin)

    1 css总结9:内边距和外边距 通过css总结8:盒子模型可知:内边距(padding),外边距(margin).可以影响盒子在浏览器的位置. 1.1 padding使用:{padding:上 右 ...

  8. web大文件上传控件-监控fd_create流程-Xproer.HttpUploader6

      监控fd_create流程 1.打开ie,f12 2.启动网络监控 点击开始捕获 上传文件夹,然后查看监控 将监控信息转到详细视图

  9. (转)正则表达式—RegEx(RegularExpressio)(三)

    原文地址:http://www.cnblogs.com/feng-c-x/archive/2013/09/05/3302465.html 今日随笔,继续写一点关于正则表达式的 知识.前两天介绍了正则表 ...

  10. C# 中使用using的三种方法

    1.using指令 using+命名空间,这种方法基本学习过C#的都用过,好处在于,写代码的时候不需要指定详细的命名空间 using System.Windows.Media; using Syste ...