【BZOJ-1576】安全路径Travel Dijkstra + 并查集
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
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
输入解释:
跟题中例子相同
Sample Output
3
6
输出解释:
跟题中例子相同
HINT
Source
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 + 并查集的更多相关文章
- BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集
传送门 BZOJ 4569 题解 ST表和并查集是我认为最优雅(其实是最好写--)的两个数据结构. 然鹅!他俩加一起的这道题,我却--没有做出来-- 咳咳. 正解是这样的: 类似ST表有\(\log ...
- HDU5441 Travel 离线并查集
Travel Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, ...
- [BZOJ 4668]冷战(带边权并查集+启发式合并)
[BZOJ 4668]冷战(并查集+启发式合并) 题面 一开始有n个点,动态加边,同时查询u,v最早什么时候联通.强制在线 分析 用并查集维护连通性,每个点x还要另外记录tim[x],表示x什么时间与 ...
- bzoj 2959 长跑(LCT+BCC+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2959 [题意] n个点,提供操作:连边,修改点权,查询自定义边的方向后起点a终点b能经 ...
- HDU 5441 Travel(并查集+统计节点个数)
http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给出一个图,每条边有一个距离,现在有多个询问,每个询问有一个距离值d,对于每一个询问,计算出有多少点 ...
- bzoj 3669: [Noi2014]魔法森林(并查集+LCT)
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- BZOJ 2333 SCOI2011 棘手的操作 并查集+可并堆
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2333 ..题意概述就不写了,各位老爷如果是看着玩的可以去搜一下,如果是做题找来的也知道题干 ...
- HDU 5441——Travel——————【并查集+二分查界限】
Travel Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Su ...
- BZOJ 1016 星球大战starwar(逆向-并查集)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1015 题意:给出一个图.每次删掉一个点,求删掉之后连通块个数. 思路:正着做不好做,我们 ...
随机推荐
- Iterator遍历器 调用Symbol.Iterator属性,遍历器对象。
Iterator实现原理 创建一个指针对象,指向当前数据结构的起始位置.也就是说,遍历器对象本质上,就是一个指针对象. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员. 第二次调 ...
- spring mvc总结1
1,spring下载 spring更改了官方网站后,找了很长时间没有找到相关的jar包下载路径,然后在网上终于找到相关的路径了 有个树形结构可供选择:http://repo.spring.io/rel ...
- 学习jQuery的on事件
开发asp.net mvc程序,多少是离不开jQuery客户程序.今天Insus.NET学习jQuery的一个on事件驱动. 先在网页视图放一个图片铵钮,用户可以使用mouse对这图片时行over,o ...
- 转:openwrt中luci学习笔记
原文地址:openwrt中luci学习笔记 最近在学习OpenWrt,需要在OpenWrt的WEB界面增加内容,本文将讲述修改OpenWrt的过程和其中遇到的问题. 一.WEB界面开发 ...
- MVP 实例
引言 可能有的朋友已经看过我翻译的Jean-Paul Boodhoo的 模型-视图-提供器 模式 一文了(如果没有,建议你先看下再看这篇文章,毕竟这两篇是紧密联系的).在那篇文章中,作者为了说明 MV ...
- QT 常用控件二
QT提供QHBoxLayout类.QVBoxlayout类及QGridLayout类等的基本布局管理,分别是水平排列布局,垂直排列布局和网格排列布局 addWidget()方法用于向布局中加入需要布局 ...
- codevs2806 红与黑
难度等级:白银 codevs2806 红与黑 题目描述 Description 有一个矩形房间,覆盖正方形瓷砖.每块瓷砖涂成了红色或黑色.一名男子站在黑色的瓷砖上,由此出发,可以移到四个相邻瓷砖之一, ...
- JMS + jboss EAP 6.2 示例
.Net中如果需要消息队列功能,可以很方便的使用微软自带的MSMQ,对应到Java中,这个功能就是JMS(Java Message Service). 下面以Jboss EAP 6.2环境,介绍一下基 ...
- PRML读书会第十二章 Continuous Latent Variables(PCA,Principal Component Analysis,PPCA,核PCA,Autoencoder,非线性流形)
主讲人 戴玮 (新浪微博: @戴玮_CASIA) Wilbur_中博(1954123) 20:00:49 我今天讲PRML的第十二章,连续隐变量.既然有连续隐变量,一定也有离散隐变量,那么离散隐变量是 ...
- JSON简介以及用法汇总
什么是JSON? JavaScript 对象表示法(JavaScript Object Notation). JSON是一种轻量级的数据交换格式,某个JSON格式的文件内部譬如可以长成这样: { &q ...