[USACO09JAN]安全出行Safe Travel
什么神仙题啊,我怎么只会\(dsu\)啊
我们考虑一个非常暴力的操作,我们利用\(dsu\ on \ tree\)把一棵子树内部的非树边都搞出来,用一个堆来存储
我们从堆顶开始暴力所有的边,如果这条边指向的另外一个点不在当前子树里,我们就把这条边计入答案
这样复杂度显然不是很对,因为我们每次可能要把子树里的边全都访问上一次
考虑让这个暴力的复杂度科学一点
我们发现,如果有一条边在当前这个节点不合法,也就是指向了一个子树内部的边,非常显然,这个点在更往上的点里也会不合法,所以我们直接在这里把这条边给删掉,这样我们就能保证每一条边最多只会被暴力一次了
代码
#include<set>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define re register
#define LL long long
#define mp std::make_pair
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int inf=999999999;
typedef std::pair<int,int> pii;
const int maxn=1e5+5;
struct E{int v,nxt,w;}e[maxn<<1];
int n,m,num,ans[maxn],Son,__;
int pre[maxn],head[maxn],sum[maxn],son[maxn],dfn[maxn];
std::set<pii> s[maxn];
std::set<pii>::iterator it;
typedef std::pair<int,pii> Pi;
std::priority_queue<Pi,std::vector<Pi>,std::greater<Pi> > q;
inline void Con(int x,int y,int z) {
e[++num].v=y;e[num].nxt=head[x];
head[x]=num;e[num].w=z;
}
void dfs1(int x) {
sum[x]=1;dfn[x]=++__;
for(re int i=head[x];i;i=e[i].nxt) {
pre[e[i].v]=pre[x]+e[i].w;
dfs1(e[i].v);sum[x]+=sum[e[i].v];
if(sum[e[i].v]>sum[son[x]]) son[x]=e[i].v;
}
}
namespace Dij {
std::priority_queue<pii,std::vector<pii>,std::greater<pii> > q;
struct E{int v,nxt,w;}e[400005];
int d[maxn],vis[maxn],fa[maxn];
int num,head[maxn];
inline void add(int x,int y,int z) {
e[++num].v=y;e[num].nxt=head[x];
head[x]=num;e[num].w=z;
}
inline void work() {
for(re int x,y,z,i=1;i<=m;i++) {
x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
for(re int i=2;i<=n;i++) d[i]=inf;
q.push(mp(0,1));
while(!q.empty()) {
int k=q.top().second;q.pop();
if(vis[k]) continue;vis[k]=1;
for(re int i=head[k];i;i=e[i].nxt)
if(d[e[i].v]>d[k]+e[i].w) {
d[e[i].v]=d[k]+e[i].w;fa[e[i].v]=k;pre[e[i].v]=e[i].w;
q.push(mp(d[e[i].v],e[i].v));
}
}
for(re int i=2;i<=n;i++) Con(fa[i],i,pre[i]);
dfs1(1);
for(re int i=1;i<=n;i++)
for(re int j=head[i];j;j=e[j].nxt) {
if(fa[i]==e[j].v||fa[e[j].v]==i) continue;
s[i].insert(mp(e[j].v,pre[e[j].v]+pre[i]+e[j].w));
}
}
}
void calc(int x) {
for(it=s[x].begin();it!=s[x].end();++it) {
pii now=(*it);
q.push(mp(now.se,mp(x,now.fi)));
}
for(re int i=head[x];i;i=e[i].nxt)
if(Son!=e[i].v) calc(e[i].v);
}
inline void del(int a,int b,int c) {
it=s[a].find(mp(b,c));s[a].erase(it);
}
void dfs(int x,int k) {
for(re int i=head[x];i;i=e[i].nxt)
if(son[x]!=e[i].v) dfs(e[i].v,0);
if(son[x]) dfs(son[x],1);
if(x==1) return;
Son=son[x],calc(x);Son=0;
while(!q.empty()) {
int now=q.top().fi,k=q.top().se.se,t=q.top().se.fi;
if(dfn[k]>=dfn[x]&&dfn[k]<=sum[x]+dfn[x]-1) {del(t,k,now);q.pop();continue;}
ans[x]=now-pre[x];break;
}
if(!k) while(!q.empty()) q.pop();
}
int main() {
n=read(),m=read();Dij::work();
dfs(1,1);
for(re int i=2;i<=n;i++)
if(!ans[i]) puts("-1");else printf("%d\n",ans[i]);
return 0;
}
[USACO09JAN]安全出行Safe Travel的更多相关文章
- luogu P2934 [USACO09JAN]安全出行Safe Travel
题目链接 luogu P2934 [USACO09JAN]安全出行Safe Travel 题解 对于不在最短路树上的边(x, y) 1 | | t / \ / \ x-----y 考虑这样一种形态的图 ...
- P2934 [USACO09JAN]安全出行Safe Travel
P2934 [USACO09JAN]安全出行Safe Travel https://www.luogu.org/problemnew/show/P2934 分析: 建出最短路树,然后考虑一条非树边u, ...
- 洛谷—— 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 ...
- ●洛谷P2934 [USACO09JAN]安全出行Safe Travel
题链: https://www.luogu.org/problemnew/show/P2934 题解: 最短路(树),可并堆(左偏堆),并查集. 个人感觉很好的一个题. 由于题目已经明确说明:从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 ...
- P2934 [USACO09JAN]安全出行
图论瞎搞...... solution: 按例化简:给定一个无向图,保证单源最短路唯一,求每个点到1号点的最短路最后一条边被封锁的情况下的最短路 乍一看,应该是次短路,但是稍微用脚趾头想想都能发现不是 ...
随机推荐
- Spring-IOC实现【02-其他实现方式】
接上文Spring-IOC实现[01-XML配置方式] Java配置方式 SpringBoot流行之后,Java 配置开始被广泛使用. Java配置本质上,就是使用一个Java类去代替xml配置,这种 ...
- MONGODB(四)——DBObject与JavaBean转换
一.DBObject 转为 JavaBean /** * 将实体Bean对象转换成DBObject * */ public static <T> DBObject beanToDBObje ...
- ECMAScript 引用类型
Object对象 新建对象 var obj = new Object() var obj ={} var obj={age:23} ... hasOwnProperty(property) 方法 va ...
- C#语句 分支语句 if --- else ---
语句是指程序命令,都是按照顺序执行的.语句在程序中的执行顺序称为“控制流”或“执行流”. 根据程序对运行时所收到的输入的响应,在程序每次运行时控制流可能有所不同. 注意,语句间的标点符号必须是英文标点 ...
- 乐字节-Java8新特性之Date API
上一篇文章,小乐给大家带来了Java8新特性之Optional,接下来本文将会给大家介绍Java8新特性之Date API 前言: Java 8通过发布新的Date-Time API来进一步加强对日期 ...
- 使用Via浏览器+ADM下载器突破百度网盘下载限速
1.下载必要工具 via浏览器 ADM下载器 2.自定义 UA UA 是一串特殊字符,用来告诉所访问的网站,手机使用的操作系统及版本.CPU 类型.浏览器及版本等信息.UA 内容如下: Mozilla ...
- HappenBefore
计算机芯片在操作指令的步骤: 1.获取指令 2.指令进行解码 3.去寄存器里取值 4.开始计算结果(操作) 5.将结果写会到寄存器中 执行代码的顺序可能与编写代码不一致,及虚拟机优化代码顺序,则为指令 ...
- spring项目获取ServletContext
(1)生命周期 ServletContext中的属性的生命周期从创建开始,到服务器关闭而 (2).获取ServletContext 1.request获取servletContext ServletC ...
- 洛谷P2447 [SDOI2010]外星千足虫(异或方程组)
题意 题目链接 Sol 异或高斯消元的板子题. bitset优化一下,复杂度\(O(\frac{nm}{32})\) 找最优解可以考虑高斯消元的过程,因为异或的特殊性质,每次向下找的时候找到第一个1然 ...
- python之线程相关操作(补充)
1 线程的其他方法 import threading import time from threading import Thread, current_thread def f1(n): time. ...