[JSOI2007]重要的城市 floyd:最短路计数
题解:
其实感觉还是比较妙的,第一眼看题想到floyd统计最短路条数,
注意到对于任意两点x,y而言,floyd将会枚举其最短路所可能经过的所有中转点,
因此我们可以直接分别统计对于所有二元组而言,最短路上必须经过的中转点,
最后遍历一次所有统计到的结果,并用bool数组标记一个地点是否被作为过中转点
最后再遍历一次bool数组,如果是中转点就输出即可
注意有多条最短路并不一定意味着这两个点之间的最短路就没有关键点,
因为这几条最短路可能有一个(或多个)共同用点,这时共同用点将成为关键点
首先来看一下我是怎么统计的:
if(f[i][j] > f[i][k] + f[k][j])
{
tot=;//error!!!!要是找到一条更短的这个当然也要清空
f[i][j] = f[i][k] + f[k][j];
q[i][j][++tot] = k;
g[i][j] = ;
}
else if(f[i][j] == f[i][k] + f[k][j])
{
now = g[i][k] * g[k][j];
if(now)//防止1 ~ 3 以1为中转这种情况
{
g[i][j] += now;
tot = ;
}
}
每次找到一条更短的路,就清空队列并重新统计最短路 + 放入中转点 + 标记最短路条数为1
如果找到了一条与当前最短路等长的路,那么就进行判断,
如果不是以自己为中转的话,那我就去掉所有中转标记(为什么这样是对的?为什么不会漏掉?)
好吧,貌似有点想明白了。
这个时候将会有两种情况:
1,出现了一条完全不同的最短路(也就是说两条最短路没有共同用点)
这时显然没有关键点,因为两条最短路不会相互影响,断了一条可以走另外一条,
所以这时是可以删的
2,出现了一条不同最短路,但这条最短路与之前的最短路有共同用点
这时虽然是有关键点的,但是我们还是可以删掉。
为什么?
这里我想了很久,其实是这样的:
注意到如果是这样的情况,那必然是类似于这样的图:
其中画红圈的显然就是关键点了,
此时由于有多条最短路(我们假设图中的所有路径都是最短的)
那么s ---> t将不会记录任何关键的,
但是我们可以观察到一个很妙的性质!
那就是关键点的出现必然是由于某条路径的唯一性所导致的,
例如图中的s ---> 2
如果s ---> 2的路径不是唯一的,那么1将不会成为关键点,
那么这意味这什么?
意味着虽然s ---> t没有统计到1,但是s ---> 2却可以统计到!
因为s ---> 2时已经没有边来干扰它们了,这条路径是唯一的!
所以我们依然可以删除,因为只要有一条边统计到了这个关键点就足够了。
在做这道题的时候我曾经陷入一个误区,虽然说比较弱智,但还是说一下吧:
就是这样一条路径:
1 ---> 2 ---> 3 ---> 4
为什么最短路计数不会统计到2条呢?
其实是因为k是放在最外层枚举的,这样的话,以2为中转的时候,3还没有成为过中转点,
因此2 ---> 4其实是不通的,因此此时不会统计到任何最短路,直到k == 3时才会统计到最短路。
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 210
#define inf 2139062143
#define getchar() *o++
/*虽然为一条链的时候两个端点可能不会统计全所有的中转?
但是小的部分还是会统计到的?*/
char READ[],*o=READ;
int n,m;
int f[AC][AC],g[AC][AC];
int q[AC][AC][AC],Head[AC][AC];
bool z[AC];
inline int read()
{
int x=;char c=getchar();
while(c > '' || c < '') c=getchar();
while(c >= '' && c <= '') x=x*+c-'',c=getchar();
return x; } inline void upmin(int &a,int b)
{
if(b < a) a = b;
} void pre()
{
int a,b,c;
n=read(),m=read();
memset(f,,sizeof(f));
for(R i=;i<=n;i++) f[i][i]=;
for(R i=;i<=m;i++)
{
a=read(),b=read(),c=read();
if(c < f[a][b])
{
f[a][b] = f[b][a] = c;
g[a][b] = g[b][a] = ;
}
}
} #define tot Head[i][j]
void work()
{
int now;
for(R k=;k<=n;k++)
for(R i=;i<=n;i++)
{
if(f[i][k] == inf) continue;
for(R j=;j<=n;j++)
{
if(f[k][j] == inf) continue;
if(f[i][j] > f[i][k] + f[k][j])
{
tot=;//error!!!!要是找到一条更短的这个当然也要清空
f[i][j] = f[i][k] + f[k][j];
q[i][j][++tot] = k;
g[i][j] = ;
}
else if(f[i][j] == f[i][k] + f[k][j])
{
now = g[i][k] * g[k][j];
if(now)//防止1 ~ 3 以1为中转这种情况
{
g[i][j] += now;
tot = ;
}
}
}
}
} void getans()
{
bool done=false;
for(R i=;i<=n;i++)
for(R j=;j<=n;j++)
{
if(tot)
{
for(R k=;k<=tot;k++)
z[q[i][j][k]] = true;
done = true;
}
}
for(R i=;i<=n;i++)
if(z[i]) printf("%d ",i);
if(!done) printf("No important cities.\n");
} int main()
{
// freopen("in.in","r",stdin);
fread(READ,,,stdin);
pre();
work();
getans();
// fclose(stdin);
return ;
}
[JSOI2007]重要的城市 floyd:最短路计数的更多相关文章
- BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 2343 Solved: 1266[Submit][Status][Discuss] Descripti ...
- 【floyd】【bitset】洛谷 P1841 [JSOI2007]重要的城市 题解
bitset玄学完美优化复杂度? 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向计 ...
- 最短路【洛谷P1841】 [JSOI2007]重要的城市
P1841 [JSOI2007]重要的城市 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向 ...
- 洛谷 P1841 [JSOI2007]重要的城市 解题报告
P1841 [JSOI2007]重要的城市 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向 ...
- Floyd最短路算法
Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...
- 【啊哈!算法】算法6:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有 ...
- 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有 ...
- 1491. [NOI2007]社交网络【最短路计数】
Description 在社交网络(socialnetwork)的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题. 在一个社交圈子里有n个人,人与人之间有不同程度的关系.我们将这 ...
- 洛谷P2047 [NOI2007]社交网络 [图论,最短路计数]
题目传送门 社交网络 题目描述 在社交网络(social network)的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题.在一个社交圈子里有n个人,人与人之间有不同程度的关系. ...
随机推荐
- selenium元素定位(三)
使用selenium就不可避免的要提到界面元素定位,通过元素定位来实现一系列的逻辑操作. selenium提供了8中元素定位的方式: id.name.class name.tag name.link ...
- Linux命令应用大词典-第34章 打印与传真
34.1 lpr:打印文件 34.2 lpq:显示打印队列状态 34.3 lprm:取消打印作业 34.4 lpstat:显示cups状态信息 34.5 cupsaccept:接受作业发送到目的地 3 ...
- 安装mysql-5.7.12-winx64
之前安装mysql时未做总结,换新电脑,补上安装记录,安装的时候,找了些网友的安装记录,发现好多坑 1.mysql-5.7.12-winx64.zip下载 官方下载地址:http://dev.mysq ...
- lesson 22 by heart
lesson 22 by heart on end = continuously 连续不断地 know/learn sth by heart 记忆sth falter: speak hesitantl ...
- 初学Direct X(8) ——碰撞检测
初学Direct X(8) --碰撞检测 真正让一个游戏鹤立鸡群的是程序对碰撞的响应有多好,这里介绍两种检测的方法: 1) 基于边框的碰撞检测 2) 基于距离的碰撞检测 1. 基于边框的碰撞检测 1. ...
- Vuejs 实现简易 todoList 功能 与 组件
todoList 结合之前 Vuejs 基础与语法 使用 v-model 双向绑定 input 输入内容与数据 data 使用 @click 和 methods 关联事件 使用 v-for 进行数据循 ...
- jQuery 对象 与 原生 DOM 对象 相互转换
区别 jQuery 选择器得到的 jQuery对象 和 原生JS 中的document.getElementById() document.querySelector取得的 DOM对象 是两种不同类型 ...
- 校招小白机考入坑之从键盘输入java的各种数据类型
//1.从键盘输入一个整型(其他基本类型类似) Scanner sc =new Scanner(System.in); sc.hasNextInt(); int str1 = sc.nextInt() ...
- 剑指offer-二叉树搜索树与双向链表25
题目描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. class Solution: def Convert(self, pRo ...
- 论文阅读之Joint cell segmentation and tracking using cell proposals
论文提出了一种联合细胞分割和跟踪方法,利用细胞segmentation proposals创建有向无环图,然后在该图中迭代地找到最短路径,为单个细胞提供分割,跟踪和事件. 3. PROPOSAL GE ...