[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个人,人与人之间有不同程度的关系. ...
随机推荐
- sphinx生成cakephp文档
cakephp的文档是用一个叫sphinx程序生成的 这个程序是python写的,所以我们要用sphinx本机必须先装python. 编译过程在Ubuntu下进行,默认Ubuntu已经安装了pytho ...
- 「Python」Convert map object to numpy array in python 3
转自Stackoverflow.备忘用. Question In Python 2 I could do the following: import numpy as np f = lambda x: ...
- 180611-Spring之RedisTemplate配置与使用
logo 文章链接:https://liuyueyi.github.io/hexblog/2018/06/11/180611-Spring之RedisTemplate配置与使用/ Spring ...
- tpo-10 C1 How to get photographs exhibited
第 1 段 1.Listen to a conversation between a student and her Photography professor. 听一段学生和摄影学教授的对话. 第 ...
- SpringCloud IDEA 教学 (四) 断路器(Hystrix)
写在开始 在SpringCloud项目中,服务之间相互调用(RPC Remote Procedure Call —远程过程调用),处于调用链路底层的服务产生不可用情况时,请求会产生堆积使得服务器线程阻 ...
- 五:Edits Viewer离线日志查看器
离线日志查看器可以将二进制日志翻译成可读的文件(如XML),只有当hadoop集群停止时才能使用.输入文件支持的类型:XML和二进制.输出文件支持类型:XML 二进制 Stats(标准输出?) ...
- 使用Python进行AES加密和解密
摘录于:http://blog.csdn.net/nurke/article/details/77267081 另外参考:http://www.cnblogs.com/kaituorensheng/p ...
- 接口_GET请求_基于python
1.GET请求(不带参数) # coding:utf-8 import requests r=requests.get("https://www.baidu.com") #r即为r ...
- POJ 2631 Roads in the North(求树的直径,两次遍历 or 树DP)
题目链接:http://poj.org/problem?id=2631 Description Building and maintaining roads among communities in ...
- Javascript闭包演示【转】
文章出自http://www.cnblogs.com/snandy/archive/2011/03/01/1967628.html 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5 ...