题意:给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径。

对于80%的数据环的个数<=1

对于100%的数据N<=10000,Q<=10000

思路:bzoj原题

只会80,正解听说是仙人掌

对于80每个询问的最优解必定是一棵树或一棵树+一条边,因为环的个数<=1

倍增LCA求距离,枚举树上加哪条边即可

 var f,g:array[..,..]of longint;
head,vet,next,fa,dep,a,b,c,len:array[..]of longint;
n,i,tx,ty,tz,ans,w,tot,m,q,x,y,j:longint; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function lca(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=f[x,i];
for i:= downto do
if f[x,i]<>f[y,i] then
begin
x:=f[x,i]; y:=f[y,i];
end;
if x=y then exit(x);
exit(f[x,]);
end; function clac(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
clac:=;
for i:= to do
if d and (<<i)> then
begin
clac:=clac+g[x,i];
x:=f[x,i];
end;
end; function ask(x,y:longint):longint;
var t:longint;
begin
t:=lca(x,y);
exit(clac(x,t)+clac(y,t));
end; function find(k:longint):longint;
begin
if fa[k]<>k then fa[k]:=find(fa[k]);
exit(fa[k]);
end; procedure dfs(u,pre:longint);
var i,e,v:longint;
begin
for i:= to do
begin
if dep[u]<<<i then break;
f[u,i]:=f[f[u,i-],i-];
g[u,i]:=g[u,i-]+g[f[u,i-],i-];
end;
e:=head[u];
while e<> do
begin
v:=vet[e];
if v<>pre then
begin
dep[v]:=dep[u]+;
f[v,]:=u; g[v,]:=len[e];
dfs(v,u);
end;
e:=next[e];
end;
end; begin
assign(input,'sp.in'); reset(input);
assign(output,'sp.out'); rewrite(output);
readln(n,m,q);
for i:= to n do fa[i]:=i;
for i:= to m do
begin
readln(tx,ty,tz);
x:=find(tx); y:=find(ty);
if x<>y then
begin
fa[y]:=x;
add(tx,ty,tz);
add(ty,tx,tz);
end
else begin inc(w); a[w]:=tx; b[w]:=ty; c[w]:=tz; end;
end;
dfs(,-);
for i:= to q do
begin
read(tx,ty);
ans:=ask(tx,ty);
for j:= to w do
begin
ans:=min(ans,ask(tx,a[j])+c[j]+ask(ty,b[j]));
ans:=min(ans,ask(ty,a[j])+c[j]+ask(tx,b[j]));
end;
writeln(ans);
end;
close(input);
close(output);
end.

最新文章

  1. 如何修复VUM在客户端启用之后报数据库连接失败的问题
  2. DOM系列---进阶篇【转】
  3. shell编程基础(2)---&amp;&amp;与||
  4. Usage of readonly and const
  5. windows server 2008 集成raid卡驱动
  6. Spring概述--1
  7. Android中使用PullToRefreshListView遇到的问题
  8. sql语句读取所有父子标签
  9. VMdomainXml
  10. mahout第一篇-----Mahout学习路线图
  11. HDU-2031-进制转换
  12. VS与Windbg调试
  13. centos静态绑定IP地址
  14. 知识点【JavaScript模块化】
  15. APUE 3rd
  16. Android学习之Fragment解析
  17. LINUX第四周学习
  18. WebAssembly 介绍
  19. git hub 建立公钥
  20. fastdfs5.11+centos7.2 按照部署(三)【转载】

热门文章

  1. 虚拟机设置NAT
  2. Java Object类 instanceof关键字 练习:判断是否为同一人 集合按照人的年龄排序,如果年龄相同按名字的字母顺序升序 Comparator比较器
  3. AutoLayout处理UITableView动态高度
  4. NSString 使用 copy、strong
  5. C# 使用Epplus导出Excel [4]:合并指定行
  6. 函数的扩展——箭头函数this的使用
  7. dev gridview columns代码管理
  8. logback写日志
  9. windows使用批处理bat文件批量打开程序
  10. python 监控日志