bzoj 1576: [Usaco2009 Jan]安全路经Travel(dijkstra堆优化+并查集)
来源:互联网 发布:淘宝网运动器材 编辑:程序博客网 时间:2024/06/06 16:42
1576: [Usaco2009 Jan]安全路经Travel
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 968 Solved: 330
[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
输入解释:
跟题中例子相同
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
输入解释:
跟题中例子相同
Sample Output
3
3
6
输出解释:
跟题中例子相同
3
6
输出解释:
跟题中例子相同
HINT
Source
Gold
题解:最短路+并查集
用dijkstra的堆优化建立最短路树,并记录最短路上的边,每个节点的父亲节点和节点在树中的深度。
因为最短路树上的1-i路径中的最后一条边是不能通过的,所以就是在最短路树中加一条边,从另一个方向到底当前点
前面的都不变,只是我们这次不用线段树维护,而是先把所有不再最短路树中的边加到一个结构体中,然后按照dis[u]+v+dis[nw]从小到大排序,因为权值小的靠前,所有第一次更新的一定是最小的,这样的话每个点至多会被更新一次,那么我们可以把一条链上的点用并查集并到一起,并查集的编号就是树链顶端点的father,这样在求lca 上的路径时,算完一个点就直接蹦到她所属的链顶的上一个(即记录的fa[x]的值),这样每个点最多被计算一次。保证正确性的同时,也保证了科学的时间负责度。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#define pa pair<int,int>#define inf 1000000000#define N 400003using namespace std;int n,m;int tot,u[N],vis[N],point[N],v[N],next[N],fa[N],pre[N],d[N],mark[N];int f[N],nw[N],ans[N],num,deep[N],dis[N];struct data {int x,y,len;};data a[N];void add(int x,int y,int z){tot++; next[tot]=point[x]; point[x]=tot; u[tot]=y; v[tot]=z; nw[tot]=x;tot++; next[tot]=point[y]; point[y]=tot; u[tot]=x; v[tot]=z; nw[tot]=y;}int cmp(data a,data b){return a.len<b.len;}void dijkstra(){priority_queue<pa,vector<pa>,greater<pa> > q;for (int i=1;i<=n;i++) dis[i]=inf;dis[1]=0; deep[1]=1; q.push(make_pair(0,1));while(!q.empty()){int now=q.top().second; q.pop();if (vis[now]) continue;vis[now]=1;for (int i=point[now];i;i=next[i]) if (dis[now]+v[i]<dis[u[i]]) { dis[u[i]]=dis[now]+v[i]; mark[pre[u[i]]]=0; pre[u[i]]=i; deep[u[i]]=deep[now]+1; mark[i]=1; f[u[i]]=now; q.push(make_pair(dis[u[i]],u[i])); }}}int find(int x){if (fa[x]==x) return x;fa[x]=find(fa[x]);return fa[x];}void solve(int u,int v,int k){int x=find(u); int y=find(v);while (x!=y){if (deep[x]<deep[y]) swap(x,y);ans[x]=k-dis[x];num++;fa[x]=f[x];x=find(fa[x]);}}int main(){scanf("%d%d",&n,&m);for (int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); }dijkstra();int cnt=0;for (int i=1;i<=m;i++) if (!mark[i*2-1]&&!mark[i*2]) { cnt++; a[cnt].x=nw[i*2]; a[cnt].y=u[i*2]; a[cnt].len=dis[nw[i*2]]+dis[u[i*2]]+v[i*2]; }sort(a+1,a+cnt+1,cmp);for (int i=1;i<=n;i++) ans[i]=-1,fa[i]=i;for (int i=1;i<=cnt;i++){ solve(a[i].x,a[i].y,a[i].len); if (num==n-1) break; } for (int i=2;i<=n;i++) printf("%d\n",ans[i]);}
0 0
- bzoj 1576: [Usaco2009 Jan]安全路经Travel(dijkstra堆优化+并查集)
- [Usaco2009 Jan]安全路经Travel dijkstra + 并查集
- [BZOJ1576][Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)
- bzoj1576[Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)
- [删边最短路 并查集] BZOJ 1576 [Usaco2009 Jan]安全路经Travel
- 【BZOJ 1576】 [Usaco2009 Jan]安全路经Travel
- bzoj 1576 [Usaco2009 Jan]安全路经Travel
- bzoj 1576[Usaco2009 Jan]安全路经Travel
- [Usaco2009 Jan]安全路经Travel(最短路树+并查集/树链剖分)
- 1576: [Usaco2009 Jan]安全路经Travel
- 【最短路径树+可并堆/树链剖分】BZOJ1576 [Usaco2009 Jan]安全路经Travel
- BZOJ 1576: [Usaco2009 Jan]安全路经Travel【最短路树】【树链剖分】
- 【bzoj1576】[Usaco2009 Jan]安全路经Travel
- BZOJ1576: [Usaco2009 Jan]安全路经Travel
- [bzoj1576] [Usaco2009 Jan]安全路经Travel
- [BZOJ1576] [Usaco2009 Jan]安全路经Travel
- BZOJ1576——[Usaco2009 Jan]安全路经Travel
- BZOJ1576 洛谷P2934 : [Usaco2009 Jan]安全路经Travel
- shell学习笔记-文件描述符及重定向
- 判断js对象是否拥有某一个属性的js代码
- 用Navicat进行数据结构同步操作
- 已知圆心,半径,角度,求圆上的点坐标
- Github
- bzoj 1576: [Usaco2009 Jan]安全路经Travel(dijkstra堆优化+并查集)
- IOS UIViewController如何透明 与安卓的Activiy的区别,新手学习
- mysql truncate/delete/drop 删除表数据
- poj 2187(凸包+旋转卡壳)
- 绑定qt的sqldriver一起发布。
- HDOJ(HDU) 2078 复习时间
- 写了一个定时器类,以方便应用
- Mysql跨平台(Windows,Linux,Mac)使用与安装
- Linux配置Jenkins建立Maven Job持续发布项目到Tomcat