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 ...
随机推荐
- What Is a Computer System?
What Is a Computer System? A combination of Five or Six Elements The term computer is used to descri ...
- MySQL语法一:数据定义语句
MySQL语句语法主要分为以下三大类: 一.数据定义语句DDL(CREATE,ALTER,DROP,DECLARE) 数据定义语句是用于修改表结构的. 一).语法提炼: 二).由上图可知,数据定义语句 ...
- CAAnimation 动画支撑系统
Model支撑:(依附对象) 从presentLayer获取数据: 渲染树为私有: -(void)addAnimation:(CAAnimation *)anim forKey:(NSString * ...
- Linux_脚本——使用echo从一个文件写入还有一个文件末尾
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/svitter/article/details/30980923 echo $(cat 你须要的文件) ...
- Mac 导入maven项目详解
1.打开Eclipse,选择Help->Install New SoftWare2.点击add 地址输入:http://m2eclipse.sonatype.org/sites/m2e,name ...
- textarea使换行变顿号
window.onload = function(){ document.getElementById('area').addEventListener('keydown',function(e){ ...
- 19、配置嵌入式servlet容器(下)
使用外置的Servlet 嵌入式Servlet容器:应用打成可执行的j ar 优点:简单.便携: 缺点:默认不支持JSP.优化定制比较复杂 使用定制器[ServerProperti ...
- c#返回值的理解
我感觉没什么用...就是在别的地方用的时候可以直接以Add(a,b)这样的方式赋值就行,不用再用c这个中间变量去接收了,希望有一天有大佬能给我讲讲设置返回值有什么好处
- 关于最新版AFNetworking(3.0)上传多张图片的问题
最新版的AF已经废弃了很多以前的类,所以很多以前的方法都不能用了,当然最主要还是为了适应ipV6所做的更改.楼主最近正在写多张图片上传,碰到了一些问题,解决之后直接封装了一个方法,废话有点多了,上代码 ...
- 十五、详述 IntelliJ IDEA 插件的安装及使用方法
正文 首先,进入插件安装界面: Mac:IntelliJ IDEA -> Preferences -> Plugins; Windows:File -> Settings -> ...