/*
* 对于不在最短路树上的边(x, y)
* 1
* |
* |
* t
* / \
* / \
* x-----y
* 考虑这样一种形态的图, ‘-’ 标记为非最短路树的边
* 对于边集(x, t)内的任意一点 i, 到达它的所有方式一定是 1 -> t -> y -> x -> i
* 这样就可以对树边(x, t)标记 Min = dis[y] + dis[x] + W_{x,y}
* 每个点在标记中取最小
* Answer_i 就是 Min_i - dis[i]
*/
#include <bits/stdc++.h> const int N = 4e3 + , M = 1e5 + ; struct Node {
int u, v, w, nxt;
} G[M << ], E[M << ];
int n, m;
int head[N], now, js, dis[N]; #define gc getchar() inline int read() {
int x = ; char c = gc;
while(c < '' || c > '') c = gc;
while(c >= '' && c <= '') x = x * + c - '', c = gc;
return x;
} inline void write_int(int x) {
printf("%d\n", x);
} inline void Add(int u, int v, int w) {
G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now;
} int fa[N], deep[N], topp[N], size[N], son[N], tree[N], Tree; void Dfs_1(int u, int f_, int dep) {
fa[u] = f_, deep[u] = dep, size[u] = ;
for(int i = head[u]; ~ i; i = G[i].nxt) {
int v = G[i].v;
if(v == f_) continue;
dis[v] = dis[u] + G[i].w;
Dfs_1(v, u, dep + );
size[u] += size[v];
if(size[v] > size[son[u]]) son[u] = v;
}
} void Dfs_2(int u, int tp) {
topp[u] = tp, tree[u] = ++ Tree;
if(!son[u]) return ;
Dfs_2(son[u], tp);
for(int i = head[u]; ~ i; i = G[i].nxt)
if(G[i].v != fa[u] && G[i].v != son[u]) Dfs_2(G[i].v, G[i].v);
} const int oo = ;
int Minn[N << ]; #define lson jd << 1
#define rson jd << 1 | 1 void Build_tree(int l, int r, int jd) {
Minn[jd] = oo;
if(l == r) return ;
int mid = (l + r) >> ;
Build_tree(l, mid, lson), Build_tree(mid + , r, rson);
} void Sec_G(int l, int r, int jd, int x, int y, int w) {
if(x <= l && r <= y) {
Minn[jd] = std:: min(Minn[jd], w);
return ;
}
int mid = (l + r) >> ;
if(x <= mid) Sec_G(l, mid, lson, x, y, w);
if(y > mid) Sec_G(mid + , r, rson, x, y, w);
} void Sec_G_imp(int x, int y, int w) {
int tpx = topp[x], tpy = topp[y];
while(tpx != tpy) {
if(deep[tpx] < deep[tpy]) std:: swap(tpx, tpy), std:: swap(x, y);
Sec_G(, n, , tree[tpx], tree[x], w);
x = fa[tpx], tpx = topp[x];
}
if(x == y) return ;
if(deep[x] < deep[y]) std:: swap(x, y);
Sec_G(, n, , tree[y] + , tree[x], w);
} int Ans[N]; void Dfs_tree(int l, int r, int jd) {
if(l == r) {
Ans[l] = Minn[jd];
return ;
}
int mid = (l + r) >> ;
Minn[lson] = std:: min(Minn[lson], Minn[jd]);
Minn[rson] = std:: min(Minn[rson], Minn[jd]);
Dfs_tree(l, mid, lson), Dfs_tree(mid + , r, rson);
} int main() {
n = read(), m = read();
for(int i = ; i <= n; i ++) head[i] = -;
for(int i = ; i <= m; i ++) {
int u = read(), v = read(), w = read(), opt = read();
if(opt) Add(u, v, w), Add(v, u, w);
else E[++ js].u = u, E[js].v = v, E[js].w = w;
}
Dfs_1(, , );
Dfs_2(, );
Build_tree(, n, );
for(int i = ; i <= js; i ++) {
int x = E[i].u, y = E[i].v;
Sec_G_imp(x, y, dis[x] + dis[y] + E[i].w);
}
Dfs_tree(, n, );
for(int i = ; i <= n; i ++) {
if(Ans[tree[i]] == oo) write_int(-);
else write_int(Ans[tree[i]] - dis[i]);
}
return ;
}

bzoj3694的更多相关文章

  1. bzoj3694最短路

    bzoj3694最短路 Description 给出一个n个点m条边的无向图,n个点的编号从1~n,定义源点为1.定义最短路树如下:从源点1经过边集T到任意一点i有且仅有一条路径,且这条路径是整个图1 ...

  2. [bzoj3694]最短路_树链剖分_线段树

    最短路 bzoj-3694 题目大意:给你一个n个点m条边的无向图,源点为1,并且以点1为根给出最短路树.求对于2到n的每个点i,求最短路,要求不经过给出的最短路树上的1到i的路径上的最后一条边. 注 ...

  3. [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)

    [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...

  4. 「BZOJ3694」「FJ2014集训」最短路

    「BZOJ3694」「FJ2014集训」最短路 首先树剖没得说了,这里说一下并查集的做法, 对于一条非树边,它会影响的点就只有u(i),v(i)到lca,对于lca-v的路径上所有点x,都可通过1-t ...

  5. [bzoj3694]最短路

    Description 给出一个$n$个点$m$条边的无向图,$n$个点的编号从$1-n$,定义源点为$1$. 定义最短路树如下:从源点$1$经过边集$T$到任意一点$i$有且仅有一条路径,且这条路径 ...

  6. 最短路 BZOJ3694 树链剖分+线段树

    分析: 树剖裸题,[Usaco2009 Jan]安全路经Travel 的简化版 剖开最短路树,遍历每一条没在最短路树上的边. 这种情况下,有且仅有u到v路径上,出来lca之外的点能够通过这条边到达,并 ...

  7. bzoj3694: 最短路(树链剖分/并查集)

    bzoj1576的帮我们跑好最短路版本23333(双倍经验!嘿嘿嘿 这题可以用树链剖分或并查集写.树链剖分非常显然,并查集的写法比较妙,涨了个姿势,原来并查集的路径压缩还能这么用... 首先对于不在最 ...

  8. bzoj1576 3694

    两道题目本质是一样的bzoj1576我们先要用dij+heap处理出最短路径树和起点到每个点的最短路径而bzoj3694已经给出了最短路径树,所以直接dfs即可题目要求的是不走起点到每个点最短路径上的 ...

  9. luogu 2934

    同 bzoj3694 需要先求出最短路树 #include <iostream> #include <cstdio> #include <algorithm> #i ...

随机推荐

  1. go 常量定义和使用

    常量的定义与变量类似,只不过使用 const 关键字. 常量可以是字符.字符串.布尔或数字类型的值. 常量不能使用 := 语法定义. 常量必须定义时赋值,不能多次赋值 package main imp ...

  2. Python开发【第三章】:文件操作

    一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...

  3. Java Web 深入分析(5) Java ClassLoader 工作机制

    Classloader 有3个作用 将class加载到JVM中去 审查每个类由谁去加载,是一种父优先的等级加载 把Class字节码统一编译成JVM统一要求的对象格式 ClassLoader的等级加载机 ...

  4. Node中的net模块提供的前端通信

    Node中的net模块提供的前端通信 客户端 业务: 客户端现在要在终端输入内容,然后回车发送内容给服务器 解决: Node中提供了一个叫做 readline 的 模块用于读取命令行内容 [ 单行读取 ...

  5. leetcode-64. 最小路径和 · vector + DP

    题面 Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right wh ...

  6. nginx搭建反向代理服务器详解

    一.反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从 ...

  7. Linux 下DNS详解

    配置之前先了解一下bind DNS服务器软件:BIND是一种开源的DNS(Domain Name System)协议的实现,包含对域名的查询和响应所需的所有软件.它是互联网上最广泛使用的一种DNS服务 ...

  8. python基础应用---格式化输出

    python的格式化输出,原来不是很理解,现在有点了解了,为此特意写一个博客来记录一下,以便自己会忘记了,随时查看, 程序主体 #格式化输出之一 name = input("pls inpu ...

  9. [Python] Codecombat 攻略 Sarven 沙漠 (1-43关)截止至36关

    首页:https://cn.codecombat.com/play语言:Python 第二界面:Sarven沙漠(43关)时间:4-11小时内容:算术运算,计数器,while循环,break(跳出循环 ...

  10. 深入理解Kubernetes资源限制:内存

    写在前面 当我开始大范围使用Kubernetes的时候,我开始考虑一个我做实验时没有遇到的问题:当集群里的节点没有足够资源的时候,Pod会卡在Pending状态.你是没有办法给节点增加CPU或者内存的 ...