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. DirectoryBrowserMiddleware中间件如何呈现目录结构

    DirectoryBrowserMiddleware中间件如何呈现目录结构 和StaticFileMiddleware中间件一样,DirectoryBrowserMiddleware中间本质上还是定义 ...

  2. httpserver

    改了下 # -*- coding:utf-8 -*- from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler HOST = &quo ...

  3. GET请求参数为中文时乱码分析

    问题描述 近期做任务时,跟后端联调时遇到一个问题,前端发送get请求,当参数值有中文时,请求失败,请求参数变为乱码.(ps:一般当参数有中文时,很少使用get请求,而是使用post请求来传输数据,请求 ...

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

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

  5. 软件工程(DBSD2016) Git Review

    说明:任何问题请在评论区说明,会集中更新回复. 连连看组 源码: git clone https://git.coding.net/jx8zjs/llk.git 提交日志 一共有20次commit日志 ...

  6. 文件夹管理工具(MVC+zTree+layer)(附源码)

    写在前 之前写了一篇关于 文件夹与文件的操作的文章  操作文件方法简单总结(File,Directory,StreamReader,StreamWrite )  把常用的对于文件与文件夹的操作总结了一 ...

  7. K-means算法和矢量量化

    语音信号的数字处理课程作业——矢量量化.这里采用了K-means算法,即假设量化种类是已知的,当然也可以采用LBG算法等,不过K-means比较简单.矢量是二维的,可以在平面上清楚的表示出来. 1. ...

  8. 基于DDD的.NET开发框架 - ABP依赖注入

    返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...

  9. node 学习笔记 - path 处理

    本文同步自我的个人博客:http://www.52cik.com/2015/12/04/learn-node-path.html path 模块是 node 用于整理.转换.合并路径的神器,只要是路径 ...

  10. Scala入门之函数进阶

    /** * 函数式编程进阶: * 1,函数和变量一样作为Scala语言的一等公民,函数可以直接赋值给变量: * 2, 函数更长用的方式是匿名函数,定义的时候只需要说明输入参数的类型和函数体即可,不需要 ...