~~~题面~~~

题解:

其实感觉还是比较妙的,第一眼看题想到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. GoF设计模式

    GOF23种设计模式简介 GoF(“四人帮”,指Gamma, Helm, Johnson & Vlissides, Addison-Wesley四人)提出的23种设计模式可谓经典,由于其定义比 ...

  2. 一个CookieContainer的拓展类

    最近项目中需要频繁用到服务器返回的Cookie,由于项目采用的是HttpClient,并且用CookieContainer自动托管Cookie,在获取Cookie的时候不太方便.所以就写了个拓展类. ...

  3. 分享开源的GB/T-2260国家行政区划代码

    项目中需要用到省市数据,在网上搜了一下,很多旧数据,稍微新一点的下载就要积分.X币什么的,很不爽,最后在GitHub上找到一个开源的,还有各种语言版本的,非常方便! https://github.co ...

  4. PHP使用Redis消息队列

    1.redis安装 参考:菜鸟教程http://www.runoob.com/redis/redis-install.html 2.安装php的redis扩展 1)phpinfo()查看php版本信息 ...

  5. 在Android上运用Anko和Kotlin开发数据库:SQLite从来不是一件轻松的事(KAD25)

    作者:Antonio Leiva 时间:Mar 30, 2017 原文链接:https://antonioleiva.com/databases-anko-kotlin/ 事实告诉我们:在Androi ...

  6. Linux命令应用大词典-第44章 PPPoE配置

    44.1 pppoe-setup:配置PPPoE客户端 44.2 ppoe-connect:管理PPPoE链路 44.3 pppoe-start:启动PPPoE链路 44.4 pppoe-stop:关 ...

  7. Java Swing学习笔记——创建JFrame

    创建显示一个空JFrame import javax.swing.JFrame; public class JFrameDemo extends JFrame{ public JFrameDemo() ...

  8. MaxScript代码补全插件

    MaxScript代码补全插件 作者Nik,原文发布于ScriptSpot 安装后max自带脚本编辑器会有自动补全,效果如下:

  9. CSP201609-1:最大波动

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  10. vmware centOS上网配置笔记

    ⦁    修改/etc/sysconfig/network-scripts/ifcfg-eth0文件  (首先查看本机vmware 虚拟网络编辑器中的网关) 重启网络 使用命令:service net ...