1576: [Usaco2009 Jan]安全路经Travel

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1044  Solved: 363
[Submit][Status][Discuss]

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

输出解释:

跟题中例子相同

HINT

Source

Gold

Solution

比较简单的一道题

首先我们跑一遍最短路,得到最短路树,在松弛操作的时候加一句话即可

然后我们发现对于不在最短路树上的边,如果把它加入树中,会形成一个环,它会影响这个环上除lca的其他点

样例是这样的,黑边是指最短路树上的边,加入非树红边,影响的是红点,加入非树蓝边,有影响的是蓝点

所发生的影响就是,环上点x,在加入边<u,v>会被更新成dis[u]+dis[v]+val<u,v>-dis[x]

所以要求被更新后最小,就是要求dis[u]+dis[v]+val<u,v>最小,那么我们按照这个价值对非树边排序

从权值小的开始更新。

所以这样的话,中间会更新一些重复的,我们只要保证那些重复的不被更新即可,这个显然可以利用并查集维护一下

这样时间复杂度大概是$O(nlogn+n×a(n))$

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 100010
#define MAXM 200010
int N,M;
struct EdgeNode{int next,to,t,from;}edge[MAXM<<];
int head[MAXN],cnt=;
void AddEdge(int u,int v,int w) {cnt++; edge[cnt].from=u; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].t=w;}
void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,w);}
#define Pa pair<int,int>
#define INF 0x7fffffff
priority_queue<Pa,vector<Pa>,greater<Pa> >q;
int dis[MAXN],fa[MAXN];
void Dijkstra(int S)
{
for (int i=; i<=N; i++) dis[i]=INF;
q.push(make_pair(,S)); dis[S]=;
while (!q.empty())
{
int now=q.top().second;
int Dis=q.top().first;
q.pop();
if (Dis>dis[now]) continue;
for (int i=head[now]; i; i=edge[i].next)
if (Dis + edge[i].t < dis[edge[i].to])
dis[edge[i].to]=Dis+edge[i].t,
fa[edge[i].to]=now,
q.push(make_pair(dis[edge[i].to],edge[i].to));
}
}
int f[MAXN];
int F(int x) {if (!f[x]) return x; else return f[x]=F(f[x]);}
struct RoadNode
{
int u,v,t;
bool operator < (const RoadNode & A) const
{return t<A.t;}
}road[MAXM];
int tot,num;
int ans[MAXN];
void Add(RoadNode x)
{
int u=x.u,v=x.v,t=x.t;
while (F(u)!=F(v))
{
num++;
if (dis[F(u)]<dis[F(v)]) swap(u,v);
ans[F(u)]=min(ans[F(u)],t-dis[F(u)]);
u=f[F(u)]=fa[F(u)];
}
}
int main()
{
N=read(),M=read();
for (int x,y,z,i=; i<=M; i++) x=read(),y=read(),z=read(),InsertEdge(x,y,z);
Dijkstra();
for (int i=; i<=cnt; i+=)
{
int u=edge[i].from,v=edge[i].to;
if (fa[u]!=v && fa[v]!=u)
road[++tot].u=u,road[tot].v=v,road[tot].t=dis[u]+dis[v]+edge[i].t;
}
sort(road+,road+tot+);
// for (int i=1; i<=tot; i++)
// printf("%d %d %d\n",road[i].u,road[i].v,road[i].t);
// for (int i=1; i<=N; i++) printf("%d ",dis[i]); puts("");
for (int i=; i<=N; i++) ans[i]=INF;
for (int i=; i<=tot && num<N-; i++) Add(road[i]);
for (int i=; i<=N; i++) printf("%d\n",ans[i]==INF? -:ans[i]);
return ;
}

写完就A了....

【BZOJ-1576】安全路径Travel Dijkstra + 并查集的更多相关文章

  1. BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集

    传送门 BZOJ 4569 题解 ST表和并查集是我认为最优雅(其实是最好写--)的两个数据结构. 然鹅!他俩加一起的这道题,我却--没有做出来-- 咳咳. 正解是这样的: 类似ST表有\(\log ...

  2. HDU5441 Travel 离线并查集

    Travel Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, ...

  3. [BZOJ 4668]冷战(带边权并查集+启发式合并)

    [BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...

  4. bzoj 2959 长跑(LCT+BCC+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2959 [题意] n个点,提供操作:连边,修改点权,查询自定义边的方向后起点a终点b能经 ...

  5. HDU 5441 Travel(并查集+统计节点个数)

    http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给出一个图,每条边有一个距离,现在有多个询问,每个询问有一个距离值d,对于每一个询问,计算出有多少点 ...

  6. bzoj 3669: [Noi2014]魔法森林(并查集+LCT)

    Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...

  7. BZOJ 2333 SCOI2011 棘手的操作 并查集+可并堆

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 ..题意概述就不写了,各位老爷如果是看着玩的可以去搜一下,如果是做题找来的也知道题干 ...

  8. HDU 5441——Travel——————【并查集+二分查界限】

    Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  9. BZOJ 1016 星球大战starwar(逆向-并查集)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1015 题意:给出一个图.每次删掉一个点,求删掉之后连通块个数. 思路:正着做不好做,我们 ...

随机推荐

  1. 弹性返回顶部JS代码

    弹性返回顶部JS代码 弹性返回顶部JS代码点击下载

  2. ES6 数组解构赋值

    .数组解构 let [a, b, c,d] = ["aa", "bb", 77,88]; alert(a) //弹出aa 可以用babel 解析看ES5的转换结 ...

  3. Centos6 修改max user processes limits

    ulimit:显示(或设置)用户可以使用的资源的限制(limit),这限制分为软限制(当前限制)和硬限制(上限),其中硬限制是软限制的上限值,应用程序在运行过程中使用的系统资源不超过相应的软限制,任何 ...

  4. codevs 3369 膜拜

    3369 膜拜 http://codevs.cn/problem/3369/ 题目描述 Description 神牛有很多-当然-每个同学都有自己衷心膜拜的神牛.某学校有两位神牛,神牛甲和神牛乙.新入 ...

  5. Linux下源码安装ffmpeg及ffmpeg的简单使用说明

    一.编译安装 ffmpeg在安装时依赖的包和版本都很让人头疼,不同编译环境也各不相同.公司之前封装了一个又各种出错. 其实办法很简单,就是到官网一步一步按着做就行了:http://trac.ffmpe ...

  6. 【java】企业级分布式搜索平台Solr视频教程

    课程背景为了满足高可用.可扩展并容错的分布式搜索引擎.Solr是一个高性能,采用Java5开发, 基于Lucene的全文搜索服务器.同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现 ...

  7. 【分布式协调器】Paxos的工程实现-cocklebur简介(二)

    Cocklebur集群的工作原理 在集群正常工作时,整个集群只会有一个Leader,其他都是Follower.Client可以注册到某个Follower,当然也可以注册到Leader,为了减轻Lead ...

  8. C# 7.0 新特性4: 返回引用

    本文参考Roslyn项目中的Issue:#118. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 ...

  9. 多线程处理中Future的妙用

    java 中Future是一个未来对象,里面保存这线程处理结果,它像一个提货凭证,拿着它你可以随时去提取结果.在两种情况下,离开Future几乎很难办.一种情况是拆分订单,比如你的应用收到一个批量订单 ...

  10. 将Table表格导出到Excel

    1.导出当前页 效果如下: 前台代码: @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta nam ...