Gremlins最近在农场上泛滥,它们经常会阻止牛们从农庄(牛棚_1)走到别的牛棚(牛_i的目的
地是牛棚_i).每一个gremlin只认识牛_i并且知道牛_i一般走到牛棚_i的最短路经.所以它
们在牛_i到牛棚_i之前的最后一条牛路上等牛_i. 当然,牛不愿意遇到Gremlins,所以准备找
一条稍微不同的路经从牛棚_1走到牛棚_i.所以,请你为每一头牛_i找出避免gremlin_i的最
短路经的长度. 和以往一样, 农场上的M (2 <= M <= 200,000)条双向牛路编号为1..M并且能让所有牛到
达它们的目的地, N(3 <= N <= 100,000)个编号为1..N的牛棚.牛路i连接牛棚a_i
(1 <= a_i <= N)和b_i (1 <= b_i <= N)并且需要时间t_i (1 <=t_i <= 1,000)通过.
没有两条牛路连接同样的牛棚,所有牛路满足a_i!=b_i.在所有数据中,牛_i使用的牛棚_1到牛
棚_i的最短路经是唯一的. 以下是一个牛棚,牛路和时间的例子: 1--[2]--2-------+
| | |
[2] [1] [3]
| | |
+-------3--[4]--4 行程 最佳路经 最佳时间 最后牛路
p_1 到 p_2 1->2 2 1->2
p_1 到 p_3 1->3 2 1->3
p_1 到 p_4 1->2->4 5 2->4 当gremlins进入农场后: 行程 最佳路经 最佳时间 避免
p_1 到 p_2 1->3->2 3 1->2
p_1 到 p_3 1->2->3 3 1->3
p_1 到 p_4 1->3->4 6 2->4 20%的数据满足N<=200. 50%的数据满足N<=3000. 时间限制: 3秒 内存限制: 64 MB PROBLEM NAME: travel 输入格式: * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i 样例输入 (travel.in): 4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3 输入解释: 跟题中例子相同 输出格式: * 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最
短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1. 样例输出 (travel.out): 3
3
6
题解:
好题珍藏
由于最短路径唯一,那么可以把到1的最短路径连起来,形成最短路树(本蒟蒻这不懂套路)
然后我们根据题意知道,1-x的路径中,不能走的为x的父亲边,那么我们就设法绕开这条边
于是想到合法情况:从1开始先绕到非x的子树上的一个节点u,再通过该节点绕道x子树上一个节点p再从p到x
答案即为f[u]+dis(u,p)+f[p]-f[x]
那么想到用堆维护f[u]+dis(u,p)+f[p] 然后用左偏树合并,并用并查集判断是否在x的子树内即可
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
const int N=,M=,inf=2e9;
int head[N],num=;
struct Lin{
int next,to,dis;
}a[M<<],e[M<<];
void init(int x,int y,int dis){
a[++num].next=head[x];a[num].to=y;a[num].dis=dis;head[x]=num;
}
int n,m;
int gi(){
int str=;char ch=getchar();
while(ch>'' || ch<'')ch=getchar();
while(ch>='' && ch<='')str=(str<<)+(str<<)+ch-,ch=getchar();
return str;
}
struct pr{
int id,dis;
bool operator <(const pr &pp)const{
return dis>pp.dis;
}
};
priority_queue<pr>q;
bool vis[N];int f[N],pre[N];
void dj(){
int cnt=,x,u,dis;
for(int i=;i<=n;i++)f[i]=inf;
q.push((pr){,});f[]=;
while(!q.empty()){
x=q.top().id;dis=q.top().dis;q.pop();
if(vis[x] || f[x]!=dis)continue;
cnt++;vis[x]=true;if(cnt==n)break;
for(int i=head[x];i;i=a[i].next){
u=a[i].to;
if(f[x]+a[i].dis<f[u])f[u]=f[x]+a[i].dis,pre[u]=x;
q.push((pr){u,f[u]});
}
}
}
int fa[N],ans[N];
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
struct node{
int val,dis,id;
node *l,*r;
int ldis(){return l?l->dis:;}
int rdis(){return r?r->dis:;}
}T[N*];
node *root[N],*pos=T;
node *merge(node *p,node *q){
if(!p || !q)return p?p:q;
if(p->val>q->val)swap(p,q);
p->r=merge(p->r,q);
if(p->ldis()<p->rdis())swap(p->l,p->r);
p->dis=p->rdis()+;
return p;
}
void delet(int x){
root[x]=merge(root[x]->r,root[x]->l);
}
void dfs(int x,int last){
int u;
fa[x]=x;
for(int i=head[x];i;i=a[i].next){
u=a[i].to;if(u==last)continue;
if(f[x]+a[i].dis==f[u]){
dfs(u,x);
fa[find(u)]=find(x);
root[x]=merge(root[x],root[u]);
}
}
node *tmp;
for(int i=head[x];i;i=a[i].next){
u=a[i].to;
if(u==last || find(u)==find(x))continue;
tmp=pos++;tmp->l=NULL;tmp->r=NULL;tmp->val=f[u]+a[i].dis+f[x];tmp->id=u;
root[x]=merge(root[x],tmp);
}
while(root[x] && find(root[x]->id)==find(x))delet(x);
if(root[x])ans[x]=root[x]->val-f[x];
else ans[x]=-;
}
void work()
{
int x,y,z;
n=gi();m=gi();
for(int i=;i<=m;i++){
x=gi();y=gi();z=gi();
init(x,y,z);init(y,x,z);
}
dj();dfs(,);
for(int i=;i<=n;i++)printf("%d\n",ans[i]);
}
int main()
{
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
work();
}

 

[USACO Jan09] 安全路径的更多相关文章

  1. 151. [USACO Dec07] 建造路径

    ★★   输入文件:roads.in   输出文件:roads.out   简单对比 时间限制:1 s   内存限制:128 MB 译 by CmYkRgB123 描述 Farmer John 刚刚得 ...

  2. [SinGuLaRiTy] 树链问题

    [SinGuLaRiTy-1035] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 关于树链 树链是什么?这个乍一看似乎很陌生的词汇表达的其 ...

  3. [CSP-S模拟测试]:城市游戏(图论+DP)

    题目传送门(内部题109) 输入格式 第一行,两个整数$n,m$. 接下来$m$行,每行三个整数$u,v,l$,描述了一条道路连接的两个路口的编号以及道路的长度. 输出格式 输出一行一个整数,为所求的 ...

  4. BZOJ1718:[USACO]Redundant Paths 分离的路径(双连通分量)

    Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numb ...

  5. [usaco jan 09] 安全路径 travel [最短路径树]

    题面: 传送门 思路: 既然最后一条边不能走,那么就一定是换了一条路,一条不经过这最后一条边的路 如果想要这条路最短,那么其在路上一定尽可能多地走了最短路径 因此,我们对这张图跑一遍从1开始的单源最短 ...

  6. USACO 回文的路径

    传送门 这道题和传纸条在某些方面上非常的相似.不过这道题因为我们要求回文的路径,所以我们可以从中间一条大对角线出发去向两边同时进行DP. 这里就有了些小小的问题.在传纸条中,两个路径一定是同时处在同一 ...

  7. luogu题解 P2860[USACO冗余路径Redundant Paths] 缩点+桥

    题目链接 https://www.luogu.org/problemnew/show/P2860 https://www.lydsy.com/JudgeOnline/problem.php?id=17 ...

  8. USACO翻译:USACO 2014 FEB SILVER 三题

    USACO 2014 FEB SILVER 一.题目概览 中文题目名称 自动打字 路障 神秘代码 英文题目名称 auto rblock scode 可执行文件名 auto rblock scode 输 ...

  9. COGS130. [USACO Mar08] 游荡的奶牛[DP]

    130. [USACO Mar08] 游荡的奶牛 ★☆   输入文件:ctravel.in   输出文件:ctravel.out   简单对比时间限制:1 s   内存限制:128 MB 奶牛们在被划 ...

随机推荐

  1. javabean 是什么?

    JavaBean规范 Bean的中文含义是“豆子”,顾名思义,JavaBean是指一段特殊的Java类, 就是有默然构造方法,只有get,set的方法的java类的对象. 专业点解释是: JavaBe ...

  2. java8-Stream之数值流

    在Stream里元素都是对象,那么,当我们操作一个数字流的时候就不得不考虑一个问题,拆箱和装箱.虽然自动拆箱不需要我们处理,但依旧有隐含的成本在里面.Java8引入了3个原始类型特化流接口来解决这个问 ...

  3. 学习UI的总结

    学习前端有一段时间了,一直在看书上的理论知识,而实战项目却很少.老师常说,想要知道自己的实力有多少,知识掌握了多少,最好的方法就是去实践了,实践出真知嘛.于是在学习中,总要是通过项目的实践以及理论知识 ...

  4. EasyUI datagrid 使用小结

    用了 EasyUI 框架一段时间了,这个前端框架用起来还是挺方便的,也有很多现成的控件,看看官方文档应该还是能比较快用起来的. 在这里记录一下一些常用的控件的方法,遇到过的bug或者当初耗了一点时间来 ...

  5. c++中模板是什么?为什么要定义模板?

    一.c++中模板是什么? 首先: int Max(int x, int y) { return x > y ? x : y; } float Max(float a,float b) { ret ...

  6. 在ABPZERO中,扩展实体的方法。

    内容 介绍 扩展的抽象实体 将新属性添加给用户 添加迁移 在界面上显示地址 在用户编辑/添加功能中添加地址 扩展的非抽象类实体 获得版本的派生实体 添加迁移 在界面上添加价格 在创建/编辑版本功能中加 ...

  7. Spring之IOC(一)

    Spring之IOC(一) 对于Spring的基本概念在这里就不在赘述了. Spring的最核心的两部分则是AOP(面向切面编程)和IOC(控制反转).本篇文章主要讲我对IOC的理解. IOC:即In ...

  8. 微信小程序开发-IP地址查询-例子

    微信小程序开发  小程序搜索框  IP地址查询  搜索查询  样例 微信小程序 开发 参考   https://mp.weixin.qq.com/debug/wxadoc/dev/component/ ...

  9. JSON序列化类

    '''pyhton的dict对象可以直接序列化为JSON的{},不过很多时候 我们更喜欢用class表示对象,比如定义Student类,然后序列化''' import json class Stude ...

  10. spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求 有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧, 但是细想想 ...