201800624模拟赛T2——回家路上
题目描述
很多学生都抱怨浪费在回家路上的时间太长。这天dongdong刚走出学校大门,就听说某段路在施工(但不知道是哪条路),有可能导致他回家的时间会变长。
Dongdong给出了一张地图,图中标号为1的点是学校,标号为N的点是他家,以及一些点之间的路和走完每条路需要的时间。现在dongdong做了最坏打算,他想知道在最坏情况下,他回家的最短时间是多少。
输入格式
第一行两个数N和M,表示点的个数,边的个数。(这是无向图)
接下来M行,每行三个数A,B和V,表示点A和点B之间有一条需要走V分钟的路。
输出格式
一行,表示最坏情况下回家需要花费最少的时间。
输入样例
5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
输出样例
27
数据规模
对于70% 的数据 \(N\le 100\);
对于100% 的数据 \(N \le 1000, M \le \frac{n^{2}-n}{2}, 1\le A\le B \le N, 1 \le V \le 1000\)。
题解
这题暴力分挺多的,有70分。先求出\(1\to N\)的最短路,然后大力删除最短路上的每一条边,每删一遍都跑一遍最短路,统计一下即可。
值得一提的是,由于本题是稠密图,所以用不加任何优化的dijkstra算法比较好,(总复杂度\(O(n^3)\),因为最短路径上的边数最多只可能有\(n-1\)条),比对优化的少一只\(\log\)。
下面讲一下正解:
对于这张图,我们先以1为源点跑一遍dijkstra,记录下路径,在以N为起点跑一遍最短路。
对于任意一个结点\(T\),其最短路一定是这样的:
\(P\)可能与\(1\)点重合。
我们把每个结点的的\(P\)记录下来,我们暂且把它记为\(P_{1}, P_{2}, \cdots, P_{N}\),这我们可以用类似并查集的数据结构维护,也可以预处理出来:
/**
* ddd是P数组
* fa[x]是在1->x的最短路中x的上一个结点是什么
**/
inline int getfa(int x)
{
return ddd[x] ? ddd[x] : ddd[x] = getfa(fa[x]);
}
inline void getl(int from, int to)
{
ljc = 1;
ddd[from] = 1;
for(int i = to; i != from; i = fa[i])
ddd[i] = ljc++;
for(int i = to; i != from; i = fa[i])
{
ddd[i] = ljc - ddd[i] + 1;
mmap[i][fa[i]] = mmap[fa[i]][i] = inf;//把最短路上的边大力删除,下面会说
}
for(int i = 1; i <= n; ++i)
ddd[i] = getfa(i);
}
那么对于一条边\(f\to t\)(假设\(f\to t\)不是\(1\to t\)最短路或\(f\to N\)最短路中的一条,因为如果是我们可以忽略不计,应为这样结果是相同的),什么情况下\(1\to N\)的最短路径可能经过改变呢?
答案是当\([P_{f}, P_{t}]\)中的有一条路径被切断时。
如图,如果\(1\to P_{s}\)中的一条被切断了,那显然\(s\to N\)的最短路比\(s\to t \to N\)不劣;如果\(P_{t}\to N\)中的一条被切断了,那显然\(1\to t\)的最短路比\(1\to s \to t\)不劣。
于是,我们可以用线段树维护\(1\to N\)最短路的边如果删去最终的最短路,枚举所有除\(1\to N\)最短路边外的所有边,对于每个\(s\to t\),都把\([P_{s}, P_{t}]\)的区间与\(1\to s \to t\)取\(\min\),最终答案为所有边删去所得的最短路的最大值。
代码细节还是挺多的,调了好久(好吧可能是我太菜了)……
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
#define fill(a) memset(a, 0x3f, sizeof(a))
#define clr(a) memset(a, 0, sizeof(a))
#define dd c = getchar()
inline void read(int& x)
{
x = 0;
int dd;
for(; !isdigit(c); dd);
for(; isdigit(c); dd)
x = (x<<1) + (x<<3) + (c^48);
return;
}
#undef dd
#define maxn 1050
#define inf 0x3f3f3f3f
int mmap[maxn][maxn];//反正都是n2,就偷懒用了邻接表
int n, m;
int ljc;
struct DIJKSTRA//其实从N开始的dijkstra只要求最短路就可以了,但还是偷懒打了结构体
{
int dist[maxn];//最短路
int ddd[maxn];//刚才说的P数组
int fa[maxn];//fa[x]是在from->x的最短路中x的上一个结点是什么
bool vis[maxn];
inline void dijkstra(int from)//由于是稠密图,用不加优化的dijkstra更快
{
fill(dist);
clr(vis);
dist[from] = 0;
int noww;
for(int kk = 1; kk <= n; ++kk)
{
noww = 0;
for(int i = 1; i <= n; ++i)
if(!vis[i] && (!noww || dist[noww] > dist[i]))
noww = i;
vis[noww] = true;
for(int i = 1; i <= n; ++i)
if(!vis[i] && mmap[noww][i] + dist[noww] < dist[i])
{
dist[i] = mmap[noww][i] + dist[noww];
fa[i] = noww;
}
}
}
inline int getfa(int x)
{
return ddd[x] ? ddd[x] : ddd[x] = getfa(fa[x]);
}
inline void getl(int from, int to)
{
ljc = 1;
ddd[from] = 1;
for(int i = to; i != from; i = fa[i])
ddd[i] = ljc++;
for(int i = to; i != from; i = fa[i])
{
ddd[i] = ljc - ddd[i] + 1;
mmap[i][fa[i]] = mmap[fa[i]][i] = inf;//把最短路上的边大力删除
}
for(int i = 1; i <= n; ++i)
ddd[i] = getfa(i);
}
} fs, ft;
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
struct Tree
{
int node[maxn];
inline void build()
{
fill(node);//并不用建树,直接全赋最大值即可
}
inline void update(int l, int r, int k, int L, int R, int tt)
{
if(L <= l && r <= R)
{
node[k] = min(node[k], tt);
return;
}
int mid = (l+r) >> 1;
if(mid >= L)
update(l, mid, ls(k), L, R, tt);
if(mid < R)
update(mid+1, r, rs(k), L, R, tt);
}
inline int query(int l, int r, int k, int pla)
{
if(l == r)
return node[k];
int mid = (l+r) >> 1;
if(pla <= mid)
return min(node[k], query(l, mid, ls(k), pla));
else
return min(node[k], query(mid+1, r, rs(k), pla));
}
} tr;
int main()
{
freopen("road.in", "r", stdin);
freopen("road.out", "w", stdout);
read(n);
read(m);
fill(mmap);
for(int i = 1, f, t, d; i <= m; ++i)
{
read(f), read(t), read(d);
mmap[f][t] = mmap[t][f] = d;
}
fs.dijkstra(1);
ft.dijkstra(n);
fs.getl(1, n);
tr.build();
#define m (min(fs.dist[i] + ft.dist[j], ft.dist[i] + fs.dist[j]) + mmap[i][j])
#define l min(fs.ddd[i], fs.ddd[j]) + 1
#define r max(fs.ddd[i], fs.ddd[j])
for(int i = 1; i <= n; ++i)
for(int j = i + 1; j <= n; ++j)
if(mmap[i][j] < inf)
tr.update(1, ljc, 1, l, r, m);
#undef m
#undef l
#undef r
int ans = 0;
for(int i = 2; i <= ljc; ++i)
ans = max(ans, tr.query(1, ljc, 1, i));
printf("%d", ans);
fclose(stdin);
fclose(stdout);
return 0;
}
201800624模拟赛T2——回家路上的更多相关文章
- 模拟赛T2 交换 解题报告
模拟赛T2 交换 解题报告 题目大意: 给定一个序列和若干个区间,每次从区间中选择两个数修改使字典序最小. \(n,m\) 同阶 \(10^6\) 2.1 算法 1 按照题意模拟,枚举交换位置并比较. ...
- 跳跳虎回家(国庆10.1模拟赛T2)
题目: [题目描述] 跳跳虎在外面出去玩忘了时间,现在他需要在最短的时间内赶回家. 跳跳虎所在的世界可以抽象成一个含有 n 个点的图(点编号从 1 到 n ),跳跳虎现在在 1 号点,跳跳虎的家在 n ...
- 20161003 NOIP 模拟赛 T2 解题报告
Weed duyege的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹. 为了查出真相,duyege 准备修好电脑之后再进行一次金坷垃的模拟实验. 电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 ...
- NOIP欢乐模拟赛 T2 解题报告
小澳的坐标系 (coordinate.cpp/c/pas) [题目描述] 小澳者表也,数学者景也,表动则景随矣. 小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过. 小澳的梦境中出现了一个 ...
- [模拟赛] T2 混合图
Description Hzwer神犇最近又征服了一个国家,然后接下来却也遇见了一个难题. Hzwer的国家有n个点,m条边,而作为国王,他十分喜欢游览自己的国家.他一般 会从任意一个点出发,随便找边 ...
- 20180530模拟赛T2——绀碧之棺
题目背景 qiancl 得到了一张藏宝图,上面写了一道谜题. 题目描述 定义\(F(n)\)为 n 在十进制下各个数位的平方和,求区间\([a,b]\)中有多少\(n\)满足\(k\times F(n ...
- 20180519模拟赛T2——pretty
[问题描述] 小美今天对于数列很有兴趣.小美打算找出一些漂亮的序列.一个漂亮的序列的限制如下: 长度为 n ,而且数列里只包含 [1,n] 的整数. 要不是不降的序列就是不升的序列. 小美想知道有多少 ...
- 2019.11.11 模拟赛 T2 乘积求和
昨天 ych 的膜你赛,这道题我 O ( n4 ) 暴力拿了 60 pts. 这道题的做法还挺妙的,我搞了将近一天呢qwq 题解 60 pts 根据题目给出的式子,四层 for 循环暴力枚举统计答案即 ...
- 5.12 省选模拟赛 T2 贪心 dp 搜索 差分
LINK:T2 这题感觉很套路 但是不会写. 区间操作 显然直接使用dp不太行 直接爆搜也不太行复杂度太高. 容易想到差分 由于使得整个序列都为0 那么第一个数也要i差分前一个数 强行加一个0 然后 ...
随机推荐
- dogcom在openwrt上的使用
前提,先配置并运行mentohust(作为802.1x认证) 1,取得编译完成的可执行文件(可先在虚拟机里测试) 2,上传到路由器 3,把dogcom主程序和配置文件放在/etc/storage/do ...
- sqlserver数据库使用navicat生成数据字典
https://blog.csdn.net/Honnyee/article/details/86156832 SELECT 表名 then d.name else '' end, 表说明 then i ...
- Golang 基础语法介绍及对比(二)
传值与传参 Golong func main() { a := fmt.Println("a = ", a) // 应该输出 "a= 3" a1 := add1 ...
- 国家虚拟仿真实验教学项目共享平台(实验空间)PHP SDK
使用XJWT标准,此标准基于JSON Web Token (JWT)开发.XJWT包含三个参数:header, payload, signature,因此生成token就要先获得这三个参数. clas ...
- docker搭建php环境
前言 本文根据参考文章,自己动手试了搭建PHP环境,对里面的Dockerfile的编写 做了最新的修改,以此记录,完整代码查看传送门 说明: 镜像下载过慢,可使用国内镜像加速,具体可自行查询 根据此方 ...
- vertica单节点故障恢复 Startup Failed, ASR Required
测试环境的vertica是单节点的,无法做到故障自动恢复,需要手工处理.案例如下: 发现5433端口连接不上,vertica挂了,手工运行admintools,重新启动vertica,仍然失败,提示: ...
- Kubernetes Nacos
一.概览 Nacos 是阿里巴巴推出来的一个新开源项目,这是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台. Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单 ...
- 基于 HTML5 WebGL 的 3D 智慧隧道漫游巡检
前言 这次为大家展示的是通过 HT for Web 灵活的图型化编辑工具打造的智慧隧道监控系统.通过 HTML5 技术实现了桌面和移动端的跨平台性,同时现实了可视化运维. 这次主要跟大家分享里面的漫游 ...
- 单片机成长之路(51基础篇) - 026 基于stm89c52之单片机看门狗
基于stc89c52的看门狗,代码如下: main.c #include "stc89c5x_Quick_configuration.h" // 自定义头文件 #include & ...
- 读取数据,并以txt格式保存
/// <summary> /// 读取数据,并以txt格式保存 /// </summary> /// <param name="data">数 ...