bzoj1576 3694
两道题目本质是一样的
bzoj1576我们先要用dij+heap处理出最短路径树和起点到每个点的最短路径
而bzoj3694已经给出了最短路径树,所以直接dfs即可
题目要求的是不走起点到每个点最短路径上的最后一条边的最短路径
首先我们考虑非树边的影响,对于一条非树边(u,v),加入到最短路径树中
必然会形成一个环,对于除了LCA(u,v)以外环上的点i,走边(u,v)的最短路径长度为d[u]+w(u,v)+d[v]-d[i]
显然我们只要穷举每个非树边,然后更新每个点可行的最短路径长度即可
裸的想法当然是可以用树链剖分+线段树来完成
但是我们有更好的想法,考虑我们用最小化d[u]+w(u,v)+d[v]即可
因此我们对每条边以d[u]+w(u,v)+d[v]为关键字从小到大排序
显然,按照这个顺序当前边更新的点一定已经是最优的
我们可以考虑用并查集维护,避免点被重复更新
const inf=;
type way=record
po,len,next:longint;
end;
node=record
loc,num:longint;
end; var heap:array[..] of node;
w,e:array[..] of way;
can:array[..] of boolean;
ans,fa,f,dep,from,d,p,where:array[..] of longint;
j,i,n,m,t,x,y,z:longint; procedure change(var a,b:node);
var c:node;
begin
c:=a;
a:=b;
b:=c;
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r: longint);
var i,j: longint;
x,y:way;
begin
i:=l;
j:=r;
x:=e[(l+r) shr ];
repeat
while e[i].len<x.len do inc(i);
while x.len<e[j].len do dec(j);
if not(i>j) then
begin
y:=e[i];
e[i]:=e[j];
e[j]:=y;
inc(i);
j:=j-;
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; function getf(x:longint):longint;
begin
if f[x]<>x then f[x]:=getf(f[x]);
exit(f[x]);
end; procedure add(x,y,z:longint);
begin
inc(t);
w[t].po:=y;
w[t].next:=p[x];
w[t].len:=z;
p[x]:=t;
end; procedure up(i:longint);
var j,x,y:longint;
begin
j:=i shr ;
while j> do
begin
if heap[i].num<heap[j].num then
begin
x:=heap[i].loc;
y:=heap[j].loc;
where[x]:=j;
where[y]:=i;
change(heap[i],heap[j]);
i:=j;
j:=i shr ;
end
else break;
end;
end; procedure sift(i:longint);
var j,x,y:longint;
begin
j:=i shl ;
while j<=t do
begin
if (j<t) and (heap[j].num>heap[j+].num) then inc(j);
if heap[i].num>heap[j].num then
begin
x:=heap[i].loc;
y:=heap[j].loc;
where[x]:=j;
where[y]:=i;
change(heap[i],heap[j]);
i:=j;
j:=i shl ;
end
else break;
end;
end; procedure dij;
var i,j,mid,x,y:longint;
begin
fillchar(from,sizeof(from),);
d[]:=;
where[]:=;
heap[].loc:=;
heap[].num:=;
for i:= to n do
begin
where[i]:=i;
d[i]:=inf;
heap[i].num:=inf;
heap[i].loc:=i;
end;
for i:= to n- do
begin
x:=heap[].loc;
mid:=heap[].num;
y:=heap[t].loc;
where[y]:=;
change(heap[],heap[t]);
dec(t);
sift();
j:=p[x];
while j<>- do
begin
y:=w[j].po;
if d[y]>mid+w[j].len then
begin
fa[y]:=x;
dep[y]:=dep[x]+;
d[y]:=mid+w[j].len;
if from[y]<>- then
begin
can[from[y]]:=false;
can[from[y] xor ]:=false;
end;
from[y]:=j;
can[j]:=true;
can[j xor ]:=true;
heap[where[y]].num:=d[y];
up(where[y]);
end;
j:=w[j].next;
end;
end;
end; procedure calc(x,y,z:longint);
var px,py:longint;
begin
px:=-;
py:=-;
while getf(x)<>getf(y) do
begin
if dep[x]<dep[y] then
begin
swap(x,y);
swap(px,py);
end;
if ans[x]=- then
begin
ans[x]:=z-d[x];
if px<>- then f[px]:=x;
end
else
if px<>- then f[px]:=getf(x);
px:=getf(x);
x:=fa[px];
end;
end; begin
t:=-;
fillchar(p,sizeof(p),);
readln(n,m);
for i:= to m do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
t:=n;
dij;
t:=;
for i:= to n do
begin
j:=p[i];
f[i]:=i;
while j<>- do
begin
if not can[j] then
begin
inc(t);
e[t].po:=i;
e[t].next:=w[j].po;
e[t].len:=w[j].len+d[i]+d[w[j].po];
can[j xor ]:=true;
end;
j:=w[j].next;
end;
end;
sort(,t);
fillchar(ans,sizeof(ans),);
for i:= to t do
calc(e[i].po,e[i].next,e[i].len);
for i:= to n do
writeln(ans[i]);
end.
bzoj1576 3694的更多相关文章
- poj 3694 Network 边双连通+LCA
题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...
- POJ 3694 Network (tarjan + LCA)
题目链接:http://poj.org/problem?id=3694 题意是给你一个无向图n个点,m条边,将m条边连接起来之后形成一个图,有Q个询问,问将u和v连接起来后图中还有多少个桥. 首先用t ...
- (POJ 3694) Network 求桥个数
题目链接:http://poj.org/problem?id=3694Description A network administrator manages a large network. The ...
- poj 3694 Network(双连通分量)
题目:http://poj.org/problem?id=3694 #include <iostream> #include <cstring> #include <cs ...
- Bzoj 3694: 最短路 树链剖分
3694: 最短路 Time Limit: 5 Sec Memory Limit: 256 MBSubmit: 67 Solved: 34[Submit][Status][Discuss] Des ...
- poj 3694 Network(割边+lca)
题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...
- 【POJ 3694】 Network(割边<桥>+LCA)
[POJ 3694] Network(割边+LCA) Network Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7971 ...
- 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集
[BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...
- poj 3694 Network : o(n) tarjan + O(n) lca + O(m) 维护 总复杂度 O(m*q)
/** problem: http://poj.org/problem?id=3694 问每加一条边后剩下多少桥 因为是无向图,所以使用tarjan缩点后会成一棵树并维护pre数组 在树上连一条边(a ...
随机推荐
- JPA entity versioning (@Version and Optimistic Locking)
详情见: http://www.byteslounge.com/tutorials/jpa-entity-versioning-version-and-optimistic-locking
- Eclipse将项目部署tomcat的webapps目录
Eclipse将项目部署tomcat的webapps目录 >>>>>>>>>>>>>>>>>& ...
- gulp 前端自动化工具
一开篇 在前端开发的过程中,我们经常会碰到压缩.合并.图片script 等,于是就有了gulp 前端自动化构建工具,它能帮你在前端开发中,节省时间. 1,安装 node.js 因为gulp 构建工具是 ...
- python基础知识六
博客园的博文对每篇博文的长度似乎做了限制 面向对象编程, 在程序何种,根据操作数据的函数或语句块来设计程序.这被成为面向过程的编程.还有一种把数据和功能结合起来,用称为对象的东西包裹起来组织组织程序的 ...
- Quartz-2D绘图之路径(Paths)详解
在上篇文章中,我们简单的理解了绘图上下文,今天我们来认识一下Quartz-2D中另一个重要的概念,路径(Paths). 一.理解路径 路径定义了一个或多个形状,或是子路径.一个子路径可由直线,曲线,或 ...
- javascript入门学习笔记2
JavaScript 拥有动态类型.这意味着相同的变量可用作不同的类型: 实例 var x // x 为 undefined var x = 6; // x 为数字 var x = "Bil ...
- 使用switch case语句来显示月份的对应天数
方法一:控制台输入月份 package com.liaojianya.chapter1; import java.util.Scanner; /** * This program demonstrat ...
- MySQL常用函数 转载
一.数学函数ABS(x) 返回x的绝对值BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制)CEILING(x) 返 ...
- Linux 权限基础说明
1 权限位说明 Linux文件或目录的权限位是由个9个权限位来控制的,每三位为一组,它们分别是文件属主(owner/user)读.写.执行,用户组(Group)的读.写.执行以及(Other)其他 ...
- 【pyhton】短路逻辑
编程语言常用的逻辑if a and b:#如果a是false,那么跳过b的判断,结果直接falseif a or b:#如果a为true,那么跳过b的判断,直接true