P2685 [TJOI2012]桥
思路:
先求出最短路: d1[u] : u 到 1 的最短路, d2[u] : u 到 n 的最短路
再求出一条从 1 到 n 的最短路链,然后从链上的每一个点出发dfs, 求出:
l[u] : u 到 1 的最短路径过中和链的交点(离 1 最近的)
r[u] : u 到 n 的最短路径过中和链的交点(离 n 最近的)
然后对于一条非链上的边( u -> v ),边权为 w ,对于链上的 l[u] 到 r[v] 之间的边任意删一条边,
最短路都有可能变成 d1[u] + w + d2[v] 然后在链上维护这个的最小值,就能知道删掉链上的每条边对最短路的影响
代码:
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head const int N = 1e5 + ;
const int INF = 0x3f3f3f3f;
int n, m, u, v, w, tot, d1[N], d2[N], link[N], id[N], l[N], r[N], a[N];
int head[N], cnt = ;
bool vis[N*];
struct edge {
int to, w, nxt;
}edge[N*];
void add(int u, int v, int w) {
edge[++cnt] = {v, w, head[u]};
head[u] = cnt;
}
priority_queue<pii, vector<pii>, greater<pii> > q;
int tree[N<<], lazy[N<<];
void push_up(int rt) {
tree[rt] = min(tree[rt<<], tree[rt<<|]);
}
void push_down(int rt) {
tree[rt<<] = min(tree[rt<<], lazy[rt]);
tree[rt<<|] = min(tree[rt<<|], lazy[rt]);
lazy[rt<<] = min(lazy[rt<<], lazy[rt]);
lazy[rt<<|] = min(lazy[rt<<|], lazy[rt]);
lazy[rt] = INF;
}
void build(int rt, int l, int r) {
lazy[rt] = INF;
if(l == r) {
tree[rt] = INF;
return ;
}
int m = l+r >> ;
build(ls);
build(rs);
push_up(rt);
}
void down(int rt, int l, int r) {
if(l == r) {
a[l] = tree[rt];
return ;
}
if(lazy[rt] != INF) push_down(rt);
int m = l+r >> ;
down(ls);
down(rs);
push_up(rt);
}
void update(int L, int R, int x, int rt, int l, int r) {
if(L <= l && r <= R) {
tree[rt] = min(tree[rt], x);
lazy[rt] = min(lazy[rt], x);
return ;
}
if(lazy[rt] != INF) push_down(rt);
int m = l+r >> ;
if(L <= m) update(L, R, x, ls);
if(R > m) update(L, R, x, rs);
push_up(rt);
} void Dijkstra(int s, int *d) {
for (int i = ; i <= n; ++i) d[i] = INF;
d[s] = ;
q.push({, s});
while(!q.empty()) {
pii p = q.top();
q.pop();
int u = p.se;
if(d[u] < p.fi) continue;
for (int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].to;
int w = edge[i].w;
if(d[v] > p.fi + w) {
d[v] = p.fi + w;
q.push({d[v], v});
}
}
}
}
void dfs(int u, int s, int *bl, int *d) {
bl[u] = s;
for (int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].to;
int w = edge[i].w;
//if(vis[(i+1)/2]) continue;
if(bl[v] == && id[v] == && d[u] + w == d[v]) dfs(v, s, bl, d);
}
}
int main() {
scanf("%d %d", &n, &m);
for (int i = ; i <= m; ++i) {
scanf("%d %d %d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
Dijkstra(, d1);
Dijkstra(n, d2);
tot = ;
u = ;
while(u != n) {
link[++tot] = u;
id[u] = tot;
for (int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].to;
int w = edge[i].w;
if(d2[v] + w == d2[u]){
vis[(i+)/] = true;
u = v;
break;
}
}
}
link[++tot] = n;
id[n] = tot;
for (int i = ; i <= tot; ++i) dfs(link[i], link[i], l, d1);
for (int i = tot; i >= ; --i) dfs(link[i], link[i], r, d2);
build(, , tot-);
for (int u = ; u <= n; ++u) {
for (int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].to;
int w = edge[i].w;
if(!vis[(i+)/]) {
if(id[l[u]] < id[r[v]]) update(id[l[u]], id[r[v]]-, d1[u] + w + d2[v], , , tot-);
}
}
}
down(, , tot-);
int ans = , cnt = ;
for (int i = ; i < tot; ++i) {
if(a[i] > ans) {
ans = a[i];
cnt = ;
}
else if(a[i] == ans) {
cnt++;
}
}
if(ans == d1[n]) cnt = m;
printf("%d %d\n", ans, cnt);
return ;
}
P2685 [TJOI2012]桥的更多相关文章
- 洛谷2685 [TJOI2012]桥
[TJOI2012]桥 题目大意:给定一无向图,求删除一条边后1到n最短路的最大值,以及方案数. 做法:我们先从1为起点.从n为起点跑两边dij,获得每一个点到起点1.终点n的最短距离,其实距离和边权 ...
- [TJOI2012]桥(最短路+线段树)
有n个岛屿, m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前的能力,是不可能通过的 ...
- [TJOI2012]桥
Description 有n个岛屿,m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前 ...
- bzoj4400: tjoi2012 桥
先传代码再填坑 #include <iostream> #include <cstdio> #include <cmath> #include <cstrin ...
- BZOJ4400 TJOI2012桥(最短路+线段树)
首先找出任意一条1-n的最短路径.显然删除的边只有在该最短路上才会对最短路长度产生影响. 不会证明地给出一个找不到反例的结论:删除一条边后,新图中一定有一条1-n的最短路径上存在一条边x->y, ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 3504: [Cqoi2014]危桥 [最大流]
3504: [Cqoi2014]危桥 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1407 Solved: 703[Submit][Status] ...
- hub,桥,交换机,路由器的区别
1.四种设备在网络中的物理位置 如下图 2.这四种设备的本质 这四种设备,不管怎样,他们都是进行包的转发,只不过转发的行为有些不一样而已 3.逐一介绍 对于hub,一个包过来后,直接将包转发到其他口. ...
- 游戏测评-桥梁建造系Poly Bridge破力桥?游戏测评
最近在b站看到了谜之声的视频:大家来造桥吧! 实在是太搞笑了,看到是一款新出不久还未正式发行的游戏,兴致一来便入手玩了玩.顺手也就写下了这篇测评. POLY BRIDGE 对这个游戏名怎么起个有趣的中 ...
随机推荐
- python拼接multipart/form-data类型post请求格式
# 最近要做form-data类型接口,大多数这种格式用来文件上传,但是我们公司就是用这种格式传输请求数据. # 百度了一些基本都是files方式的,可是我们需要data=方式的.下面自己来拼接,代码 ...
- NOIP2018总结
细细想来,学习OI也有4年多的时间了,今年已经是第二次参加noip提高组了,有必要写点什么了 NOIP2018 记得在天刚蒙蒙亮的时候走进70中,这是第四次了,但紧张只增不减,在刺骨的寒风下身体微微发 ...
- 25 range打印100到0的连续整数
使用range打印100,99,98,...0for i in range(100,-1,-1): print(i)
- padding和margin
padding (内边距) 语法: (1)padding-left:10px; 左内边距 (2)padding-right:10px; 右内边距 (3)padding-top:10px; 上内边距 ( ...
- Linux中检查本地系统上的开放端口列表的方法
在 Linux 中很少有用于此目的的实用程序.然而,我提供了四个最重要的 Linux 命令来检查这一点. 你可以使用以下四个命令来完成这个工作.这些命令是非常出名的并被 Linux 管理员广泛使用.n ...
- Referer图片防盗链
前几天讲了<nginx下载防盗链>,今天继续说下图片防盗链. 他们两个使用的指令不同,前者使用secure link,并且需要程序配合,但是效果非常好;后者不需要程序配合,根据图片来源来实 ...
- nginx rewrite (转发)
1.location正则写法 一个示例: location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所 ...
- Linux网络属性管理
Linux网络属性管理 局域网:以太网,令牌环网 Ethernet: CSMA/CD 冲突域 广播域 MAC:Media Access Control 48bits: 24bits: 24bits: ...
- 记华硕小主机装xp并给nokia e7-00 刷机
前言 事情是这样的,年前给早先收的小e买了触摸外屏.这会儿有空就给它换上了屏幕,然后尝试装app的时候,发现证书有问题. 根据以往使用n73的经验,然后就百度怎么破解证书. 然后我发现,这些东西网上资 ...
- Exp6 信息搜集与漏洞扫描 20164303
一.实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 二.实践内容. (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测. ...