~~~题面~~~

题解:

其实感觉还是比较妙的,第一眼看题想到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:最短路计数的更多相关文章

  1. BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2343  Solved: 1266[Submit][Status][Discuss] Descripti ...

  2. 【floyd】【bitset】洛谷 P1841 [JSOI2007]重要的城市 题解

        bitset玄学完美优化复杂度? 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向计 ...

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

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

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

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

  5. Floyd最短路算法

    Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...

  6. 【啊哈!算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  7. 【坐在马桶上看算法】算法6:只有五行的Floyd最短路算法

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  8. 1491. [NOI2007]社交网络【最短路计数】

    Description 在社交网络(socialnetwork)的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题. 在一个社交圈子里有n个人,人与人之间有不同程度的关系.我们将这 ...

  9. 洛谷P2047 [NOI2007]社交网络 [图论,最短路计数]

    题目传送门 社交网络 题目描述 在社交网络(social network)的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题.在一个社交圈子里有n个人,人与人之间有不同程度的关系. ...

随机推荐

  1. 在hive中查询导入数据表时FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict

    当我们出现这种情况时 FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least ...

  2. map按值排序

    package com.zhilei.test; import java.util.Comparator;import java.util.HashMap;import java.util.Map;i ...

  3. serv-u自动停止的解决方法

    在主界面serv-u管理控制台-主页--管理服务器----服务器详细信息下,点击“创建,修改并删除服务器事件”找到“事件”右击空白处---“添加”然后如下图所示填写: 点击“保存”就好了,而且我自己也 ...

  4. Linux命令应用大词典-第13章 用户和组群管理

    13.1 useradd:创建用户账户 13.2 adduser:创建用户账户 13.3 lnewusers:创建用户账户 13.4 usermod:修改用户账户 13.5 userdel:删除用户账 ...

  5. zookeeper应用:屏障、队列、分布式锁

    zookeeper工具类: 获取连接实例:创建节点:获取子节点:设置节点数据:获取节点数据:访问控制等. package org.windwant.zookeeper; import org.apac ...

  6. (原) MaterialEditor部- UmateriaEditor中 Node编译过程和使用(1)

    @author: 白袍小道 转载说明原处 插件同步在GITHUB: DaoZhang_XDZ     最后YY需求(手滑) 1.在理清楚基础套路和细节后,自定义纹理资源,并加入到现有UE材质系统 2. ...

  7. Tensorflow中使用tfrecord方式读取数据-深度学习-周振洋

    本博客默认读者对神经网络与Tensorflow有一定了解,对其中的一些术语不再做具体解释.并且本博客主要以图片数据为例进行介绍,如有错误,敬请斧正. 使用Tensorflow训练神经网络时,我们可以用 ...

  8. Python3 小工具-UDP发现

    from scapy.all import * import optparse import threading import os def scan(ip): pkt=IP(dst=ip)/UDP( ...

  9. 第四课——MFC应用程序框架

    一.MFC应用程序类型 上篇文章的彩蛋:可通过使用MFC应用程序向导(MFC AppWizard)的功能来创建所需要的应用程序,这意味着不需要输入任何代码.MFC除了应用程序向导,还对应用程序项目有着 ...

  10. 软件工程 speedsnail 第二次冲刺9

    20150526 完成任务:划线的优化,速度和谐: 遇到问题: 问题1 速度仍然不满意 解决1 未解决 明日任务: 蜗牛碰到线后速度方向的调整:(做优化)