[usaco jan 09] 安全路径 travel [最短路径树]
题面:
思路:
既然最后一条边不能走,那么就一定是换了一条路,一条不经过这最后一条边的路
如果想要这条路最短,那么其在路上一定尽可能多地走了最短路径
因此,我们对这张图跑一遍从1开始的单源最短路,并建立出最短路径树
那么新的路径(1->u)一定是这样构成的:(1->v)+edge(v,w)+(w->u),其中w是u在最短路径树上的后代
那么,我们对于每一条非树边(u,v),其树上路径上所有点(除了lca)的答案,都可以被dis[u]+dis[v]+w(u,v)-dis[路径上的点]来更新
然而,直接每一次这样更新,时间效率肯定不行
对上述的结论进一步分析,可以发现,实际上dis[u]+dis[v]+w(u,v)对于每条非树边(u,v)固定
因此可以把dis[u]+dis[v]+w(u,v)排序,对于每一条非树边依次操作,并且使用并查集来跳过已经更新过得边
总时间复杂度:dij O(nlogn),排序 O(mlogm) 更新答案 O(n)
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
struct edge{
int to,w,next;
}e[];
struct new_edge{
int from,to,w;
}x[];
struct node{
int num,fa;
vector<int>son;
}a[];
int n,m,first[],pre[],dis[],f[],ans[];
bool vis[];
void spfa(){
int i,u,v,w;
queue<int>q;memset(dis,,sizeof(dis));
q.push();pre[]=;dis[]=;
while(!q.empty()){
u=q.front();q.pop();vis[u]=;
for(i=first[u];~i;i=e[i].next){
v=e[i].to;w=e[i].w;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;pre[v]=u;
if(!vis[v]){
vis[v]=;q.push(v);
}
}
}
}
}
bool cmp(new_edge l,new_edge r){
return l.w<r.w;
}
int find(int x){
return ((f[x]==x)?x:f[x]=find(f[x]));
}
int aa[],bb[],cc[];
int main(){
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
memset(first,-,sizeof(first));
memset(ans,-,sizeof(ans));
int i,j,t1,t2,t3,l,r;
scanf("%d%d",&n,&m);
for(i=;i<=m;i++){
scanf("%d%d%d",&t1,&t2,&t3);
e[i*-].to=t2;e[i*-].next=first[t1];e[i*-].w=t3;first[t1]=i*-;
e[i*].to=t1;e[i*].next=first[t2];e[i*].w=t3;first[t2]=i*;
aa[i]=t1;bb[i]=t2;cc[i]=t3;
}
spfa();
// for(i=1;i<=n;i++) cout<<pre[i]<<ends<<dis[i]<<endl;
// for(i=1;i<=m;i++) cout<<aa[i]<<ends<<bb[i]<<ends<<cc[i]<<endl;
// cout<<"end of spfa"<<endl;
for(i=;i<=n;i++){
a[i].num=i;f[i]=i;
a[i].fa=pre[i];
if(i!=) a[pre[i]].son.push_back(i);
}
int cnt=;
for(i=;i<=m;i++){
if(pre[aa[i]]==bb[i]||pre[bb[i]]==aa[i]) continue;
// cout<<aa[i]<<ends<<bb[i]<<ends<<cc[i]<<endl;
x[++cnt].from=aa[i];x[cnt].to=bb[i];x[cnt].w=dis[aa[i]]+dis[bb[i]]+cc[i];
}
// cout<<"end2"<<endl;
sort(x+,x+cnt+,cmp);
for(i=;i<=cnt;i++){
l=find(x[i].from);r=find(x[i].to);
while(l!=r){
if(dis[l]<dis[r]) swap(l,r);
ans[l]=x[i].w-dis[l];
f[l]=pre[l];l=find(l);
}
}
for(i=;i<=n;i++) printf("%d\n",ans[i]);
}
[usaco jan 09] 安全路径 travel [最短路径树]的更多相关文章
- [usaco jan 09] 气象牛 baric [dp]
题面: 传送门 思路: 题意有点绕,实际上就是给你一个计算规则,让你取最少的元素,通过这个计算方式,得到一个小于指定误差上限的结果 这个规则分为三个部分,这里分别用pre,sum,suf表示 因为给定 ...
- [BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分)
[BZOJ1576] [BZOJ3694] [USACO2009Jan] 安全路径(最短路径+树链剖分) 题面 BZOJ1576和BZOJ3694几乎一模一样,只是BZOJ3694直接给出了最短路树 ...
- [BZOJ 1576] [Usaco2009 Jan] 安全路经Travel 【树链剖分】
题目链接: BZOJ - 1576 题目分析 首先Orz Hzwer的题解. 先使用 dijikstra 求出最短路径树. 那么对于一条不在最短路径树上的边 (u -> v, w) 我们可以先沿 ...
- 【最短路径树】51nod1443 路径和树
并不是什么高端操作并且一些模型会用到 Description 给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集).从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E ...
- 安全路径——最短路径树+dsu缩边
题目描述 思路 首先想到$dijkstra$跑完之后$build$一棵最短路径树.要找到每个节点i到根的满足要求的最短路,考虑把一些非树边加进去. 对于非树边$(u,v)$,因为节点i上方的边被占领, ...
- bzoj 4016: [FJOI2014]最短路径树问题
bzoj4016 最短路路径问题 Time Limit: 5 Sec Memory Limit: 512 MB Description 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点 ...
- [BZOJ4016][FJOI2014]最短路径树问题
[BZOJ4016][FJOI2014]最短路径树问题 试题描述 给一个包含n个点,m条边的无向连通图.从顶点1出发,往其余所有点分别走一次并返回. 往某一个点走时,选择总长度最短的路径走.若有多条长 ...
- HDU4871 Shortest-path tree(最短路径树 + 树的点分治)
题目大概要先求一张边有权的图的根为1的最短路径树,要满足根到各点路径序列的字典序最小:然后求这棵最短路径树包含k个结点的最长路径的长度和个数. 首先先构造出这棵字典序最小的最短路径树..好吧,我太傻逼 ...
- POJ3013 Big Christmas Tree(最短路径树)
题目大概说给一张点和边都有权的图,现在要求其一棵以1结点为根的生成树使树的边权和最小,树边权 = 对应的图边权 * 树边末端点为根的子树所有结点对于图顶点的点权和. 要求∑(边权*子树点权和),等价于 ...
随机推荐
- 2018.5.28 Oracle数据库补充
select * from (select rownum rn,e2.* from (select e1.* from emp e1)e2 where rownum<=10)e3 where e ...
- cd ..和cd -
cd ..是返回上一层目录, cd -是返回到上一次的工作目录.
- 在mininet上基于ovs,ovx,pox搭建三点虚拟网络
本次试验基于mininet平台,在平台中利用ovs新建1个交换机,以pox为控制器,ovx作为中间层实现虚拟化. 基础请参照http://ovx.onlab.us/getting-started/tu ...
- Activiti学习记录(五)
1.排他网关 说明: 1) 一个排他网关对应一个以上的顺序流 2) 由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果. 3) 决策网关 ...
- kernel
http://sebastianraschka.com/Articles/2014_kernel_pca.html
- Repeater控件里面取不到CheckBox的值
然后在后台需要取到,选中了那些 然后在后台怎么取也取不到,当时就纳闷了,然后开始怀疑自己的代码是不是错了,经过仔细一看,我的妈呀,加载事件了差一句话......整个人都不好了 加载事件差这句话不行,补 ...
- 搜狗浏览器特性页面JS
http://ie.sogou.com/features4.2.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN ...
- 认识mysql(4)
今日是MySQL的第四篇,难度会稍微加大,加油! 开始吧! 1.外键(foreign key) 1.定义:让当前表字段的值在另一个表的范围内选择 2.语法: foreign key(参考字段名) r ...
- A Bug's Life(削弱版食物链)
Description Background Professor Hopper is researching the sexual behavior of a rare species of bug ...
- Redis之String类型操作
接口IRedisDaoStr: package com.net.test.redis.base.dao; import java.util.List; import java.util.Map; /* ...