两道题目本质是一样的
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. Eclipse优化集合,Eclipse优化速度,解决Ctrl+C、Ctrl+V卡

    Eclipse优化集合,Eclipse优化速度,解决Ctrl+C.Ctrl+V卡 >>>>>>>>>>>>>>> ...

  2. Spring4.3.1 JDBCTemplate操作数据库

    个人总结,转载请注明出处:http://www.cnblogs.com/lidabnu/p/5679354.html 基于Spring4.3.1官方文档总结,官方文档链接http://docs.spr ...

  3. OC细节 - 1.深拷贝与浅拷贝详解

    概述 拷贝:复制一个与源对象内容相同的对象 实现拷贝,需要遵守以下两个协议 NSCopying NSMutableCopying 拷贝返回对象的种类 可变,mutableCopy消息返回的对象 不可变 ...

  4. UWP textbox 只能输入数字

    private void Testbox_TextChanged(object sender, TextChangedEventArgs e) {    var textbox = (TextBox) ...

  5. 转: angularjs 指令中动态编译的方法(适用于有异步请求的情况) 内嵌指令无效

    angular的坑很多 例子: 在directive的link中有一个$http请求,当请求完成后根据返回的值动态做element.append('......');这个操作, 能显示没问题,可问题是 ...

  6. POJ 1631 Bridging signals(LIS O(nlogn)算法)

    Bridging signals Description 'Oh no, they've done it again', cries the chief designer at the Waferla ...

  7. 标准的最大margin问题

    standard large margin problem 分割线

  8. js 判断一个点是否在一个多边形之内

    出处: https://github.com/substack/point-in-polygon/blob/master/index.js github: https://github.com/sub ...

  9. Burp Suite Walkthrough

    Burp Suite is one of the best tools available for web application testing. Its wide variety of featu ...

  10. 三十项调整助力 Ubuntu 13.04 更上一层楼

    在Ubuntu 13.04 Raring Ringtail安装完成之后,我们还有三十项调整需要进行. 1.Ubuntu 13.04 Raring Ringtail安装完毕后,我又进行了一系列工作 大家 ...