[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结点为根的生成树使树的边权和最小,树边权 = 对应的图边权 * 树边末端点为根的子树所有结点对于图顶点的点权和. 要求∑(边权*子树点权和),等价于 ...
随机推荐
- angular实现全屏显示效果
- session 关于localhost和本地IP地址 不共享问题
打比方, 一个请求 localhost:8080/test/test ,一个本地Ip(172.1.1.1:8080/test/test) 1.请求localhost方式 HttpSession s ...
- windows_Bat_Scripts查看系统IP-更改regedit-更新系统补丁
1.1 脚本名称 Update_patch.bat 1.2 脚本代码 @echo off :menu cls mode con cols=48 lines=27 & color 0 ...
- php微信红包算法
微信红包算法.php /**生成红包的函数*/ function getRandMoney($totalMoney, $totalPeople=2, $miniMoney=1){ $randRemai ...
- 开源数据库中间件-MyCat
开源数据库中间件-MyCat产生的背景 如今随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系型数据库已经无法满足快速查询与插入数据的需求.这 ...
- 常用模块之 os,json,shelve,xml模块
os 即操作系统 在 os 中提供了很多关于文件,文件夹,路径处理的函数 这是我们学习的重点 os.path 是os模块下专门用于处理路径相关的 python是一门跨平台语言,由于每个平台路径规则不同 ...
- Mongodb内嵌对象关联查询
db.-10-30T00:00:00Z"),"$lt":ISODate("2018-10-30T23:59:00Z")}, "equip.$ ...
- oracle 事务 第二弹
一 数据库版本 SYS@LEO1>select* from v$version; BANNER ------------------------------------------------- ...
- Codeforces Round #472 A-D
A题: 题意:就是给你一个长度为n的字符串,有三种颜色,其中有一些‘?’的字符代表未着色,你需要找到至少有两种方法染色,同时满足相邻两个字符间不能相同: 思路:有两种染色方法的前提:首先给定的字符串中 ...
- DFS:POJ1190-生日蛋糕(基础搜索)
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K 描述 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. ...