P2934 [USACO09JAN]安全出行Safe Travel
P2934 [USACO09JAN]安全出行Safe Travel
https://www.luogu.org/problemnew/show/P2934
分析:
建出最短路树,然后考虑一条非树边u,v,w,它可以让u->lca的路径上的点x的答案更新为dis[v]+dis[u]+w-dis[x]。为从1走到v(dis[v]),从v走到u(+w),从u走到x,(dis[u]-dis[x])。
然后对于每条非树边,按照dis[v]+dis[u]+w排序,然后会发现每个点只会更新一次,然后用并查集维护。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
const int INF = 1e9; struct Edge{
int u,v,w,lca;
Edge() {}
Edge(int a,int b,int c,int d) { u = a, v = b, w = c; lca = d;}
bool operator < (const Edge &A) const {
return w < A.w;
}
}e[N];
int fa[N], far[N], ans[N], n; namespace ShortestPath{
#define pa pair<int,int>
#define mp(a,b) make_pair(a,b)
priority_queue< pa, vector< pa >, greater< pa > >q;
int head[N], nxt[N], to[N], len[N], dis[N], En;
bool vis[N];
void add_edge(int u,int v,int w) {
++En; to[En] = v; len[En] = w; nxt[En] = head[u]; head[u] = En;
++En; to[En] = u; len[En] = w; nxt[En] = head[v]; head[v] = En;
}
void dijkstra() {
for (int i=; i<=n; ++i) dis[i] = INF, vis[i] = false;
dis[] = ;
q.push(mp(dis[],));
while (!q.empty()) {
pa now = q.top(); q.pop();
int u = now.second;
if (vis[u]) continue;
vis[u] = true;
for (int i=head[u]; i; i=nxt[i]) {
int v = to[i];
if (dis[v] > dis[u] + len[i]) {
fa[v] = u;
dis[v] = dis[u] + len[i];
q.push(mp(dis[v], v)); // 居然写成了mp(v,dis[v])!!!
}
}
}
}
}
namespace Tree_Chain{
int IIIII;
int siz[N], son[N], bel[N], deth[N];
vector<int> T[N];
void dfs1(int u) {
siz[u] = ;
deth[u] = deth[fa[u]] + ;
for (int sz=T[u].size(),i=; i<sz; ++i) {
int v = T[u][i];
if (v == fa[u]) continue;
dfs1(v);
siz[u] += siz[v];
if (!son[u] || siz[v] > siz[son[u]]) son[u] = v;
}
}
void dfs2(int u,int top) {
bel[u] = top;
if (!son[u]) return;
dfs2(son[u], top);
for (int sz=T[u].size(),i=; i<sz; ++i) {
int v = T[u][i];
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);
}
}
int LCA(int u,int v) {
while (bel[u] != bel[v]) {
if (deth[bel[u]] < deth[bel[v]]) swap(u, v);
u = fa[bel[u]];
}
if (deth[u] < deth[v]) return u;
return v;
}
void Main() {
for (int i=; i<=n; ++i) T[fa[i]].push_back(i);
dfs1();
dfs2(, );
}
}
using namespace ShortestPath;
using namespace Tree_Chain; int find(int x) {
return x == far[x] ? x : far[x] = find(far[x]);
}
void Merge(int u,int v) {
u = find(u), v = find(v);
if (u != v) far[u] = v;
}
void update(int u,int lca,int v) {
u = find(u);
int x = fa[u];
while (deth[u] > deth[lca]) {
ans[u] = v; Merge(u, x);
u = find(u); x = fa[u];
}
}
int main() {
n = read(); int m = read();
for (int i=; i<=m; ++i) {
int u = read(), v = read(), w = read();
add_edge(u, v, w);
} ShortestPath::dijkstra();
Tree_Chain::Main(); int cnt = ;
for (int u=; u<=n; ++u) {
for (int i=head[u]; i; i=nxt[i]) {
int v = to[i];
if (v > u && u != fa[v] && v != fa[u])
e[++cnt] = Edge(u, v, dis[u] + dis[v] + len[i], LCA(u,v)); // e[i].w,zz的减了一个dis[lca]
}
}
for (int i=; i<=n; ++i) far[i] = i, ans[i] = INF;
sort(e + , e + cnt + );
for (int i=; i<=cnt; ++i) {
update(e[i].u, e[i].lca, e[i].w);
update(e[i].v, e[i].lca, e[i].w);
}
for (int i=; i<=n; ++i)
if (ans[i] == INF) puts("-1");
else printf("%d\n",ans[i] - dis[i]);
return ;
}
P2934 [USACO09JAN]安全出行Safe Travel的更多相关文章
- luogu P2934 [USACO09JAN]安全出行Safe Travel
题目链接 luogu P2934 [USACO09JAN]安全出行Safe Travel 题解 对于不在最短路树上的边(x, y) 1 | | t / \ / \ x-----y 考虑这样一种形态的图 ...
- ●洛谷P2934 [USACO09JAN]安全出行Safe Travel
题链: https://www.luogu.org/problemnew/show/P2934 题解: 最短路(树),可并堆(左偏堆),并查集. 个人感觉很好的一个题. 由于题目已经明确说明:从1点到 ...
- 洛谷—— P2934 [USACO09JAN]安全出行Safe Travel || COGS ——279|| BZOJ——1576
https://www.luogu.org/problem/show?pid=2934 题目描述 Gremlins have infested the farm. These nasty, ugly ...
- [USACO09JAN]安全出行Safe Travel 最短路,并查集
题目描述 Gremlins have infested the farm. These nasty, ugly fairy-like creatures thwart the cows as each ...
- 「BZOJ1576」[Usaco2009 Jan] 安全路经Travel------------------------P2934 [USACO09JAN]安全出行Safe Travel
原题地址 题目描述 Gremlins have infested the farm. These nasty, ugly fairy-like creatures thwart the cows as ...
- [USACO09JAN]安全出行Safe Travel
题目 什么神仙题啊,我怎么只会\(dsu\)啊 我们考虑一个非常暴力的操作,我们利用\(dsu\ on \ tree\)把一棵子树内部的非树边都搞出来,用一个堆来存储 我们从堆顶开始暴力所有的边,如果 ...
- P2934 [USACO09JAN]安全出行
图论瞎搞...... solution: 按例化简:给定一个无向图,保证单源最短路唯一,求每个点到1号点的最短路最后一条边被封锁的情况下的最短路 乍一看,应该是次短路,但是稍微用脚趾头想想都能发现不是 ...
- WOJ#2423 安全出行Safe Travel
描述 精灵最近在农场上泛滥,它们经常会阻止牛们从农庄(牛棚_1)走到别的牛棚(牛_i的目的 地是牛棚_i).每一个精灵只认识牛_i并且知道牛_i一般走到牛棚_i的最短路经.所以它们在牛_i到牛棚_i之 ...
- 数据结构(左偏树,可并堆):BNUOJ 3943 Safe Travel
Safe Travel Time Limit: 3000ms Memory Limit: 65536KB 64-bit integer IO format: %lld Java class ...
随机推荐
- Vue收藏资料
组件库的全局引用和按需引用:http://www.cnblogs.com/zhuanzhuanfe/p/7516745.html
- SQL表创建注意事项
CREATE TABLE V_USER ( AUTOID ), USERID BYTE) NOT NULL, USERNAME BYTE) NOT NULL, USERPASSWORD BYTE) N ...
- 在CentOS实现mysql数据库的自动备份
数据是一个比较重要的数据,经常需要备份,每次都手动比较麻烦.本脚本主要现实在CentOS中实现对数据库的备份和保留最近十五天的备份文件.避免太多无用陈旧的备份占用空间. #!/bin/bashid=& ...
- JQuery的异步回调支持 - Promise、Deferred
1.Deferred对象: 一般在函数内部进行声明,并在运行过程中改变其状态,例如成功或失败,最终返回Promise对象用于状态监听. 主要方法: Deferred.resolve(param...) ...
- BZOJ4530:[BJOI2014]大融合(LCT)
Description 小强要在N个孤立的星球上建立起一套通信系统.这套通信系统就是连接N个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的负载就是它所在的当前能够 联通的树上路过它 ...
- composer的基本运用
Composer -- PHP依赖管理的新时代 一.简介 说到composer,绝大多数的开发人员都会用到.composer是一个什么工具呢? composer 是 PHP 用来管理依赖(depend ...
- mybaitis动态sql利用bind标签代替%拼接完成模糊查询
Oracle中使用bind的写法 <select id="selectUser" resultType="user" parameterType=&quo ...
- DU1525 Euclid's Game 博弈
HDU1525 Euclid's Game 博弈 题意 给定两个数字 a, b. 每次只能用 较大的值 减去 较小的值的倍数, 两个人轮流进行操作, 第一个得到 0 的胜利. 分析 对于 a == b ...
- localtunnel内网服务器暴露至公网
摘自@scarlex 1.安装 npm install -g localtunnel 2.运行 lt --port 8080 (your url is: http://xxxx.localtun ...
- 关于结构体占用空间大小总结(#pragma pack的使用)
关于C/C++中结构体变量占用内存大小的问题,之前一直以为把这个问题搞清楚了,今天看到一道题,发现之前的想法完全是错误的.这道题是这样的: 在32位机器上,下面的代码中 class A { publi ...