【BZOJ1576】[Usaco2009 Jan]安全路经Travel

Description

Input

* 第一行: 两个空格分开的数, N和M

* 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i

Output

* 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1.

Sample Input

4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
输入解释:
跟题中例子相同

Sample Output

3
3
6
输出解释:
跟题中例子相同

题解: 先求出最短路径树,然后我们统计每条非树边对每个点的影响。一条非树边可以更新它覆盖的所有点,如果这条边(x,y,len)覆盖了z,那么ans[z]=min(ans[z],dis[x]+dis[y]+len-dis[z]),因为dis[z]是确定的,所以我们维护链上的dis[x]+dis[y]+len的最小值即可。

如何维护?树剖+线段树,倍增,都是不错的方案,当然有更巧的。将所有非树边按dis[x]+dis[y]+len从小到大排序,然后用并查集维护所有没被更新的点,暴力更新路径上没被更新的点即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <utility>
#define mp(A,B) make_pair(A,B)
using namespace std;
const int maxn=100010;
int n,m,cnt;
int to[maxn<<2],next[maxn<<2],val[maxn<<2],head[maxn],dis[maxn],fa[maxn],pre[maxn];
int f[maxn],s[maxn],ans[maxn];
bool vis[maxn];
priority_queue<pair<int,int> > q;
struct edge
{
int a,b,v;
bool ont;
}p[maxn<<1];
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int rd()
{
int ret=0,f=1; char gc=nc();
while(!isdigit(gc)) {if(gc=='-') f=-f; gc=nc();}
while(isdigit(gc)) ret=ret*10+gc-'0',gc=nc();
return ret*f;
}
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
bool cmp(const edge &a,const edge &b)
{
return a.v<b.v;
}
int find(int x)
{
return (f[x]==x)?x:(f[x]=find(f[x]));
}
int main()
{
n=rd(),m=rd();
memset(head,-1,sizeof(head));
register int i,u,a,b;
for(i=1;i<=m;i++) p[i].a=rd(),p[i].b=rd(),p[i].v=rd(),add(p[i].a,p[i].b,p[i].v),add(p[i].b,p[i].a,p[i].v);
memset(dis,0x3f,sizeof(dis));
dis[1]=0,q.push(mp(0,1));
while(!q.empty())
{
u=q.top().second,q.pop();
if(vis[u]) continue;
vis[u]=1;
for(i=head[u];i!=-1;i=next[i]) if(dis[to[i]]>dis[u]+val[i])
fa[to[i]]=u,pre[to[i]]=(i>>1)+1,dis[to[i]]=dis[u]+val[i],q.push(mp(-dis[to[i]],to[i]));
}
for(i=1;i<=n;i++) f[i]=i,p[pre[i]].ont=1;
for(i=1;i<=m;i++) p[i].v+=dis[p[i].a]+dis[p[i].b];
sort(p+1,p+m+1,cmp);
for(i=1;i<=m;i++) if(!p[i].ont)
{
a=find(p[i].a),b=find(p[i].b);
while(a!=b)
{
if(dis[a]<dis[b]) swap(a,b);
ans[a]=p[i].v-dis[a],f[a]=fa[a],a=find(f[a]);
}
}
for(i=2;i<=n;i++) printf("%d\n",(!ans[i])?-1:ans[i]);
return 0;
}

【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集的更多相关文章

  1. BZOJ1576: [Usaco2009 Jan]安全路经Travel(最短路 并查集)

    题意 给你一张无向图,保证从1号点到每个点的最短路唯一.对于每个点求出删掉号点到它的最短路上的最后一条边(就是这条路径上与他自己相连的那条边)后1号点到它的最短路的长度 Sol emmm,考场上想了个 ...

  2. BZOJ.1576.[Usaco2009 Jan]安全路经Travel(树形DP 并查集)

    题目链接 BZOJ 洛谷 先求最短路树.考虑每一条非树边(u,v,len),设w=LCA(u,v),这条边会对w->v上的点x(x!=w)有dis[u]+dis[v]-dis[x]+len的距离 ...

  3. 【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel

    有趣的思考题 Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第 ...

  4. BZOJ1576 [Usaco2009 Jan]安全路经Travel

    首先用Dijkstra做出最短路生成树,设dis[p]为1到p点的最短路长度 对于一条不在生成树上的边u -> v,不妨设fa为u.v的lca 则一fa到v的路径上的任意点x都可以由u达到,走的 ...

  5. BZOJ1576: [Usaco2009 Jan]安全路经Travel(树链剖分)

    Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...

  6. [BZOJ1576] [Usaco2009 Jan]安全路经Travel(堆优化dijk + (并查集 || 树剖))

    传送门 蒟蒻我原本还想着跑两边spfa,发现不行,就gg了. 首先这道题卡spfa,所以需要用堆优化的dijkstra求出最短路径 因为题目中说了,保证最短路径有且只有一条,所以可以通过dfs求出最短 ...

  7. bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分

    1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 665  Solved: 227[Sub ...

  8. bzoj 1576: [Usaco2009 Jan]安全路经Travel——并查集+dijkstra

    Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...

  9. BZOJ 1576: [Usaco2009 Jan]安全路经Travel

    日常自闭半小时后看题解,太弱了qwq. 感觉这道题还是比较难的,解法十分巧妙,不容易想到. 首先题目说了起点到每个点的最短路都是唯一的,那么对这个图求最短路图必定是一棵树,而且这棵树是唯一的. 那么我 ...

随机推荐

  1. 关于spring中<context:component-scan base-package="" />写法

    1.通配符形式<context:component-scan base-package="com.*" /> 2.全路径 <context:component-s ...

  2. TypeScript 映射类型

    typescript支持定义类型加入推导式后产生新的类型 属性不变 但会改变对象的使用方式 这个是类型Person中加入ReadOnly推导出的新类型 他的属性全部是只读的 这个是推导出部分属性 这是 ...

  3. WCF实现客户端和服务端

    service side 1.定义ServiceContract: 2.new a ServiceHost 3. add endpoint using System.ServiceModel; nam ...

  4. ToStringBuilder学习(一):常用方法介绍

    一.简介与引入    1.ToStringBuilder.HashCodeBuilder.EqualsBuilder.ToStringStyle.ReflectionToStringBuilder.C ...

  5. 413. Reverse Integer【easy】

    Reverse digits of an integer. Returns 0 when the reversed integer overflows (signed 32-bit integer). ...

  6. jquery实现页面的搜索功能

    $(function(){ $("input[type=button]").click(function(){ var txt=$("input[type=text]&q ...

  7. jsp tld的function 自定义方法扩展

    引入方式示例: <%@ taglib prefix="fns" uri="/WEB-INF/tlds/fns.tld" %> 写法示例: <? ...

  8. Mybatis设置超时时间

    Mybatis设置超时时间 mybatis如果不指定,默认超时时间是不做限制的,默认值为0.mybatis sql配置超时时间有两种方法: 1.全局配置 在mybatis配置文件的settings节点 ...

  9. 对java中hashmap深入理解

    1.HashMap的结构是怎样的? 二维结构,第一维是数组,第二维是链表 2.Get方法的流程是怎样的? 先调用Key的hashcode方法拿到对象的hash值,然后用hash值对第一维数组的长度进行 ...

  10. Python中集合类型(set)学习小结

    set 是一个无序的元素集合,支持并.交.差及对称差等数学运算, 但由于 set 不记录元素位置,因此不支持索引.分片等类序列的操作. 初始化 复制代码代码如下: s0 = set()d0 = {}s ...