洛谷 P1841 [JSOI2007]重要的城市 解题报告
P1841 [JSOI2007]重要的城市
题目描述
参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里。而食堂门前施工虽然也截断了原来通向计算中心的路,却没有使路程增加,因为可以找到同样长度的路作替代。其实,问题的关键在于,路截断的地方是交通要点。
同样的情况也出现在城市间的交通中。某些城市如果出了问题,可能会引起其他很多城市的交通不便。另一些城市则影响不到别的城市的交通。jsoi冬令营的同学发现这是一个有趣的问题,于是决定研究这个问题。
他们认为这样的城市是重要的:如果一个城市c被破坏后,存在两个不同的城市a和b(a, b均不等于c),a到b的最短距离增长了(或不通),则城市c是重要的。
jsoi冬令营的同学面对着一张教练组交给他们的城市间交通图,他们希望能找出所有重要的城市。现在就请你来解决这个问题。
输入输出格式
输入格式:
第一行两个整数N,M,N为城市数,M为道路数
接下来M行,每行三个整数,表示两个城市之间的无向边,以及之间的路的长度
输出格式:
一行,按递增次序输出若干的数,表示重要的城市。
说明
30%的数据: \(N\le 20\);
60%的数据: \(N\le 100\);
100%的数据: \(N\le 200,M\le \frac{N\times (N-1)}{2},0<c\le 10000\)。c即路的长度。
保证不出现重边和自环
如果没有点的话需要输出一行
“No important cities.”
去掉引号
这个题很神奇
先说说普遍的\(O(N^3)\)的做法。
一个点\(i\)称为重要点的要求:存在一对点\((u,v)\),这对点的所有最短路都经过这个点\(i\)
考虑floyd松弛的过程,如果点\(i\)松弛成功\((u,v)\),说明\(i\)至少在前\(i\)个点松弛过后的最短路上,我们先把它存起来,没错只存它(其实用bitset把所有的点存下来复杂度也是可行的而且跑到飞快),如果没松弛成功且刚好相等,那这个点被开除重要点了,不满足唯一性,踢掉。
其实说起来很不清楚,但我们大致可以感性理解。
关于为什么这样不会漏点,因为之前的点已经存了。比如说1-4被3松弛,存下\(point[1][4]=3\),而1-4最短路上其实有1,2,3,4这几个点,不过我们已经在1,3时存下了2,因此这样其实会有重复,所以我们最后统计时去个重。
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
const int N=202;
int g[N][N],n,m,point[N][N],ans[N*N],cnt;
int main()
{
scanf("%d%d",&n,&m);
memset(g,0x3f,sizeof(g));
for(int u,v,w,i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
g[u][v]=g[v][u]=w;
}
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
if(i==k) continue;
for(int j=1;j<=n;j++)
{
if(j==i||j==k) continue;
if(g[i][j]>g[i][k]+g[k][j])
{
g[i][j]=g[i][k]+g[k][j];
point[i][j]=k;
}
else if(g[i][j]==g[i][k]+g[k][j])
point[i][j]=0;
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(point[i][j])
ans[++cnt]=point[i][j];
if(!cnt) printf("No important cities.\n");
std::sort(ans+1,ans+1+cnt);
cnt=std::unique(ans+1,ans+1+cnt)-(ans+1);
for(int i=1;i<=cnt;i++)
printf("%d ",ans[i]);
return 0;
}
再提供一个比较好理解的\(O(n^3logn)\)的分治算法
在Floyd松弛的过程中,其实哪个点先松弛哪个点后松弛是无所谓的哈
而我们最后拆点走其实就是只有一个点不松弛和所有点都松弛情况的一个对比,看各点的最短路情况有没有改变
对未松弛点集\([l,r]\)
我们可以先松弛其中的一半\([l,mid]\),然后去另一半处理子问题,处理完了还原左区间,松弛右区间,再去左边处理问题
这样当区间大小为1时,就只是那个点没有参与松弛,我们对比一下即可
而对每个相同大小的区间构成的集合,它们实际上总共用了每个点松弛了一次,为\(O(N^3)\)(还原是\(O(N^2)\)的,算做常数)
一共有\(logn\)种大小的区间,所以总复杂度为\(O(N^3logn)\)
Code:
#include <cstdio>
#include <cstring>
int min(int x,int y){return x<y?x:y;}
const int N=202;
int g[N][N],n,m,flag,ans[N],d[N][N];
void divide(int l,int r)
{
if(l==r)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j&&g[i][j]<d[i][j])
{
ans[l]=1;
flag=1;
return;
}
return;
}
int tmp[N][N];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
tmp[i][j]=d[i][j];
int mid=l+r>>1;
for(int k=l;k<=mid;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
divide(mid+1,r);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=tmp[i][j];
for(int k=mid+1;k<=r;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
divide(l,mid);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=tmp[i][j];
}
int main()
{
scanf("%d%d",&n,&m);
memset(g,0x3f,sizeof(g));
memset(d,0x3f,sizeof(d));
for(int u,v,w,i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
d[u][v]=d[v][u]=g[u][v]=g[v][u]=w;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
divide(1,n);
if(!flag) printf("No important cities.\n");
for(int i=1;i<=n;i++)
if(ans[i])
printf("%d ",i);
return 0;
}
2018.8.4
洛谷 P1841 [JSOI2007]重要的城市 解题报告的更多相关文章
- 【floyd】【bitset】洛谷 P1841 [JSOI2007]重要的城市 题解
bitset玄学完美优化复杂度? 题目描述 参加jsoi冬令营的同学最近发现,由于南航校内修路截断了原来通向计算中心的路,导致去的路程比原先增加了近一公里.而食堂门前施工虽然也截断了原来通向计 ...
- 洛谷 P2323 [HNOI2006]公路修建问题 解题报告
P2323 [HNOI2006]公路修建问题 题目描述 输入输出格式 输入格式: 在实际评测时,将只会有m-1行公路 输出格式: 思路: 二分答案 然后把每条能加的大边都加上,然后加小边 但在洛谷的题 ...
- 洛谷 P1407 [国家集训队]稳定婚姻 解题报告
P1407 [国家集训队]稳定婚姻 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有关. 25岁的 ...
- 洛谷 P3237 [HNOI2014]米特运输 解题报告
P3237 [HNOI2014]米特运输 题目描述 米特是\(D\)星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题. \(D\)星上有 ...
- 洛谷 P1852 [国家集训队]跳跳棋 解题报告
P1852 [国家集训队]跳跳棋 题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在\(a\),\(b\), ...
- 洛谷 P3299 [SDOI2013]保护出题人 解题报告
P3299 [SDOI2013]保护出题人 题目描述 出题人铭铭认为给SDOI2012出题太可怕了,因为总要被骂,于是他又给SDOI2013出题了. 参加SDOI2012的小朋友们释放出大量的僵尸,企 ...
- 洛谷 P2059 [JLOI2013]卡牌游戏 解题报告
P2059 [JLOI2013]卡牌游戏 题意 有\(n\)个人玩约瑟夫游戏,有\(m\)张卡,每张卡上有一个正整数,每次庄家有放回的抽一张卡,干掉从庄家起顺时针的第\(k\)个人(计算庄家),干掉的 ...
- 洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告
P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串,定义两个串相等为"长度相同,且一个串每个数加某个数与另一个串完全相同",求所有串的最长公 ...
- 洛谷 P2774 方格取数问题 解题报告
P2774 方格取数问题 题目背景 none! 题目描述 在一个有 \(m*n\) 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...
随机推荐
- Odd CSS syntax. [class^='icon-'], [class*=' icon-']
原文: https://stackoverflow.com/questions/20322740/odd-css-syntax-class-icon-class-icon I am going thr ...
- 「日常训练」Divisibility by Eight(Codeforces Round 306 Div.2 C)
题意与分析 极简单的数论+思维题. 代码 #include <bits/stdc++.h> #define MP make_pair #define PB emplace_back #de ...
- 征战 OSG-序及目录
其实很早就应该写这个了,一直拖到现在就是因为懒啊. 自从七月演习回来,被划到三维平台开发部,就一直混日子,也没人带领,也没人问结果,就这么一直堕落下来了,直到有一天才发现自己也看不上自己了,觉得自己这 ...
- mysql新手进阶02
云想衣裳花想容,春风拂槛露华浓. 若非群玉山头见,会向瑶台月下逢. 现在有一教学管理系统,具体的关系模式如下: Student (no, name, sex, birthday, class) Tea ...
- Python安装教程最新版
Python安装教程最新版 目前Python官网已经更新到了最新版Python 3.7.1, 相比Python 2系列,它的兼容性不是太好, 不过应该会在不久的将来会全面解决.它的安装比较容易,具体步 ...
- Java并发基础--Lock的学习
一.Lock的出现 Lock的主要作用实现线程之间的同步互斥,与synchronized关键字的效果是一样的,synchronized是Java语言内置的特性,那么为什么又出现了Lock呢?原因是sy ...
- sql随机数
) as P_jsnews_id ) as P_jsnews_id) * from P_jsnews order by newid()
- [leetcode-662-Maximum Width of Binary Tree]
Given a binary tree, write a function to get the maximum width of the given tree. The width of a tre ...
- css修改placeholder的样式
css修改placeholder的样式 input::-webkit-input-placeholder { /* WebKit browsers */ font-size:14px; color: ...
- 2019寒假训练营第三次作业part2 - 实验题
热身题 服务器正在运转着,也不知道这个技术可不可用,万一服务器被弄崩了,那损失可不小. 所以, 决定在虚拟机上试验一下,不小心弄坏了也没关系.需要在的电脑上装上虚拟机和linux系统 安装虚拟机(可参 ...