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]桥的更多相关文章

  1. 洛谷2685 [TJOI2012]桥

    [TJOI2012]桥 题目大意:给定一无向图,求删除一条边后1到n最短路的最大值,以及方案数. 做法:我们先从1为起点.从n为起点跑两边dij,获得每一个点到起点1.终点n的最短距离,其实距离和边权 ...

  2. [TJOI2012]桥(最短路+线段树)

    有n个岛屿, m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前的能力,是不可能通过的 ...

  3. [TJOI2012]桥

    Description 有n个岛屿,m座桥,每座桥连通两座岛屿,桥上会有一些敌人,玩家只有消灭了桥上的敌人才能通过,与此同时桥上的敌人会对玩家造成一定伤害.而且会有一个大Boss镇守一座桥,以玩家目前 ...

  4. bzoj4400: tjoi2012 桥

    先传代码再填坑 #include <iostream> #include <cstdio> #include <cmath> #include <cstrin ...

  5. BZOJ4400 TJOI2012桥(最短路+线段树)

    首先找出任意一条1-n的最短路径.显然删除的边只有在该最短路上才会对最短路长度产生影响. 不会证明地给出一个找不到反例的结论:删除一条边后,新图中一定有一条1-n的最短路径上存在一条边x->y, ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. BZOJ 3504: [Cqoi2014]危桥 [最大流]

    3504: [Cqoi2014]危桥 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1407  Solved: 703[Submit][Status] ...

  8. hub,桥,交换机,路由器的区别

    1.四种设备在网络中的物理位置 如下图 2.这四种设备的本质 这四种设备,不管怎样,他们都是进行包的转发,只不过转发的行为有些不一样而已 3.逐一介绍 对于hub,一个包过来后,直接将包转发到其他口. ...

  9. 游戏测评-桥梁建造系Poly Bridge破力桥?游戏测评

    最近在b站看到了谜之声的视频:大家来造桥吧! 实在是太搞笑了,看到是一款新出不久还未正式发行的游戏,兴致一来便入手玩了玩.顺手也就写下了这篇测评. POLY BRIDGE 对这个游戏名怎么起个有趣的中 ...

随机推荐

  1. c# webapi上传、读取、删除图片

    public class FileAPIController : BaseController    {        private readonly string prefix = "t ...

  2. docker容器实战-----初级<2>

    第二章  docker容器 1. Docker是通过内核虚拟化技术(namespaces及cgroups cpu.内存.磁盘io等)来提供容器的资源隔离与安全保障等.由于Docker通过操作系统层的虚 ...

  3. Docker容器和本机之间的文件传输

    docker cp 本地文件路径 ID全称:容器路径

  4. Servlet基本知识总结

    Servlet 简介 Servlet是什么? Servlet是一个Java编写的程序,此程序是基于Http协议的,并运行在web服务器上或者应用服务器上.它主要是作为web浏览器或其他Http客户端的 ...

  5. 简单的Json数据

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  6. ROS kinetic语音识别

    1.安装依赖 1.1安装ros-kinetic-audio-common sudo apt-get install ros-kinetic-audio-common 1.2 安装libasound2 ...

  7. python安装pip的步骤记录

    因为重新装了系统,所以python所有的环境都要重新走一遍. 首先去python官网下载python最新版本.如果python没有自动加入环境变量的话就需要你自己手动加入.这个一般在安装python的 ...

  8. liunx驱动----点亮LED

    自动挂接根文件系统(直接从NFS启动) 修改uboot命令行 把 bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0 ...

  9. kibana查询语法 使用教程

    1. 使用双引号包起来作为一个短语搜索: "like Gecko" 2. ? 匹配单个字符; * 匹配0到多个字符 例如:kiba?a, el*search ? * 不能用作第一个 ...

  10. inodes 相关信息查看

    查看inode数量 df -ih 查看磁盘信息 tune2fs -l /dev/sdc1 查看相关目录信息 /data/osd.3/bean_test/7/8/9# debugfs /dev/sdc2 ...