两道题目本质是一样的
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的更多相关文章

  1. poj 3694 Network 边双连通+LCA

    题目链接:http://poj.org/problem?id=3694 题意:n个点,m条边,给你一个连通图,然后有Q次操作,每次加入一条边(A,B),加入边后,问当前还有多少桥,输出桥的个数. 解题 ...

  2. POJ 3694 Network (tarjan + LCA)

    题目链接:http://poj.org/problem?id=3694 题意是给你一个无向图n个点,m条边,将m条边连接起来之后形成一个图,有Q个询问,问将u和v连接起来后图中还有多少个桥. 首先用t ...

  3. (POJ 3694) Network 求桥个数

    题目链接:http://poj.org/problem?id=3694Description A network administrator manages a large network. The ...

  4. poj 3694 Network(双连通分量)

    题目:http://poj.org/problem?id=3694 #include <iostream> #include <cstring> #include <cs ...

  5. Bzoj 3694: 最短路 树链剖分

    3694: 最短路 Time Limit: 5 Sec  Memory Limit: 256 MBSubmit: 67  Solved: 34[Submit][Status][Discuss] Des ...

  6. poj 3694 Network(割边+lca)

    题目链接:http://poj.org/problem?id=3694 题意:一个无向图中本来有若干条桥,有Q个操作,每次加一条边(u,v),每次操作后输出桥的数目. 分析:通常的做法是:先求出该无向 ...

  7. 【POJ 3694】 Network(割边&lt;桥&gt;+LCA)

    [POJ 3694] Network(割边+LCA) Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 7971 ...

  8. 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集

    [BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...

  9. poj 3694 Network : o(n) tarjan + O(n) lca + O(m) 维护 总复杂度 O(m*q)

    /** problem: http://poj.org/problem?id=3694 问每加一条边后剩下多少桥 因为是无向图,所以使用tarjan缩点后会成一棵树并维护pre数组 在树上连一条边(a ...

随机推荐

  1. fsdfasfsa

    http://www.cnblogs.com/daniel206/archive/2008/01/16/1041729.html using System.IO;using System.Net;us ...

  2. jquery 如何给新生成的元素绑定 hover事件?

    $("table tr").live({    mouseenter:    function()    {       //todo    },    mouseleave:   ...

  3. 简洁JS 日历控件 支持日期和月份选择

    原文出处 以下这个JS日历控件是我的闲暇之余自己编写的,所有的代码全部在IE7/IE8/Firefox下面测试通过, 而且可以解决被iframe层遮盖的问题.现在只提供两种风格(简洁版和古典版)和两种 ...

  4. php 的一个pg_fetch_assoc的怪问题

    遇到过一种问题 . if($row=pg_fetch_assoc($result)){ while($row=pg_fetch_assoc($result)){ echo '3333'; $koCd ...

  5. C#语法糖之第四篇: 扩展方法

    今天继续分享C#4.0语法糖的扩展方法,这个方法也是我本人比较喜欢的方法.大家先想想比如我们以前写的原始类型不能满足现在的需求,而需要在该类型中添加新的方法来实现时大家会怎么做.我先说一下我没有学习到 ...

  6. JS事件监听 JS:attachEvent和addEventListener 使用方法

    attachEvent与addEventListener区别适应的浏览器版本不同,同时在使用的过程中要注意attachEvent方法          按钮onclickaddEventListene ...

  7. Javascript字符串拼接小技巧

    在Javascript中经常会遇到字符串的问题,但是如果要拼接的字符串过长就比较麻烦了. 如果是在一行的,可读性差不说,如果要换行的,会直接报错. 在此介绍几种Javascript拼接字符串的技巧. ...

  8. php返回相对时间(如:20分钟前,3天前)的方法

    function plural($num) { if ($num != 1) return "s"; } function getRelativeTime($date) { $di ...

  9. java基础部分

    1.java的基本数据类型及所占的字节 boolen  8位  1个字节 byte 8位 1个字节 char 16位 2个字节 short 16位 2个字节 int 32位 4个字 float 32位 ...

  10. PHP表单常用正则表达式(URL、HTTP、手机、邮箱等)

    <?php /** * @description: 正则表达式匹配 */ class Regex { /** * @手机号 */ public static function Phone($su ...