[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个人,人与人之间有不同程度的关系. ...
随机推荐
- iOS UIWebView加载时添加进度条01
标注:此框架仅适合UIWebView 对iOS8后新出的WKWebView不适用,当然,你可以尝试修改框架里的几个代理方法. 框架是:NJKWebViewProgress 导入头文件 #import ...
- 「日常训练」Battle Over Cities - Hard Version(PAT-TOP-1001)
题意与分析 题意真的很简单,实在不想讲了,简单说下做法吧. 枚举删除每个点,然后求最小生成树,如果这个路已经存在那么边权就是0,否则按照原来的处理,之后求花费,然后判整个图是否联通(并查集有几个roo ...
- hdu1848Fibonacci again and again(sg函数)
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- 180606-Linux下jdk中文乱码问题解决
文章链接:https://liuyueyi.github.io/hexblog/2018/06/06/180606-Linux下jdk中文乱码问题解决/ linux下jdk中文乱码问题解决 之前遇到过 ...
- TPO-15 C2 Performance on a biology exam
TPO-15 C2 Performance on a biology exam 第 1 段 1.Listen to part of a conversation between a Student a ...
- Shader Forge学习
最近学习了一下shader forge,一个屌屌哒插件用来生成shader.尽管其降低了制作shader的难度,但是真的想做出满意的shader的话还是得有一定的shader基础.但是仅仅是做出一些简 ...
- kettle_简单入门
简介 Kettle是一款纯Java开发的ETL工具,它是跨平台的,所以它可以在Window.Linux.Unix上运行.注意什么是ETL,读者可以自行百度了解,我的理解是将一个数据库的数据导入到另外一 ...
- (python)leetcode刷题笔记 02 Add Two Numbers
2. Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. ...
- Shell 常用命令、基本用法总结
Filter Filter 常用于从大量文本.数据中提取需求的部分.下面介绍几个常用的 filter 命令. cut $ cut -c 5-8 textfile.txt # 切出 textfile.t ...
- oraclize预言机资料
oraclize预言机资料 智能合约如何可信的与外部世界交互: https://blog.csdn.net/sportshark/article/details/77477842 国外一篇讲得很详细的 ...