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 ...
随机推荐
- CSAPP buffer lab记录——IA32版本
CSAPP buffer lab为深入理解计算机系统(原书第二版)的配套的缓冲区溢出实验,该实验要求利用缓冲区溢出的原理解决5个难度递增的问题,分别为smoke(level 0).fizz(level ...
- 总结:从Node爬取数据到前端图表展示
最近寒假在家学习Node.js开发,光看书或者跟着敲代码还不够,得找一点有趣的事情来玩一玩,于是我决定写一个Node爬虫,爬取一些有意思或者说是有用的数据.这个决定只与我的兴趣有关,与Python或者 ...
- 使用virtualenv的正确姿势
关于virtualenv是什么我想我不用介绍的吧.用python做开发的人要是不会用virtualenv,总有一天会被各种环境恶心死.那么我今天就来讲一讲使用virtualenv的正确姿势. virt ...
- BZOJ2565:最长双回文串(Manacher)
Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同). 输入长度为n的串S,求S的最长双回文子串T ...
- Time Zone 【模拟时区转换】(HDU暑假2018多校第一场)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6308 Time Zone Time Limit: 2000/1000 MS (Java/Others) ...
- STM32F10X固件库函数——串口清状态位函数分析
STM32F10X固件库函数——串口清状态位函数分析 最近在测试串口热插拔功能的时候,意外发现STM32F10X的串口库函数中,清理串口状态位函数稍稍有点不解.下面是改函数的源码: /******** ...
- Java语言实现简单的登陆注册
1.登录注册 1.1数据库设计 create table USER_INFO( id number not null, name ) not null, pass ) )insert into USE ...
- Mysql不同表的同名字段索引名可以相同
mysql中不同表的相同字段索引是可以重名的,因为索引文件一表一个: 命名规则: 普通索引:idx_字段名 唯一索引:ux_字段名
- 调用WebService报错404问题 (转载)
我想在MVC4的项目添加一个webservice文件,访问没问题,但是最后调用方法就报404错误. 但是如果我全新ASP.NET 空Web应用程序 然后再添加一个webservice文件,就一切OK. ...
- GoBelieve IM 服务端编译
#部署im1. 安装go编译环境参考链接:https://golang.org/doc/install 2. 下载im_service代码 cd $GOPATH/src/github.com/GoBe ...