题目大意:有t(t<=100)条无向边连接两点,求s到e刚好经过n(n<=10^7)条路径的最小距离。

第一反应分层图,但是一看n就懵逼了,不会写。看了题解之后才知道可以这么玩。。。

首先有100条边最多200个点,但点编号到1000,所以离散化一下。

先把n转成2进制,按位考虑。dist[i][j][k]表示刚好经过2^i条边从j到k的最短距离,则dist[i,j,k]=min{dist[i-1][j][l]+dist[i-1][l][k]}。用类似快速幂的方法,若是2进制的n这一位是1的话,就把答案数组g和dist跑floyd(min{g[i-1][j][l]+dist[i-1][l][k]}),否则dist自己和自己跑(min{dist[i-1][j][l]+dist[i-1][l][k]}),这样子g就是跑n条路径得出的最小距离了。

代码如下:

type
map=array[..,..]of longint;
var
n,t,s,e,i,j,k,len,x,y,tot:longint;
c,d,g:array[..,..]of longint;
num:array[..]of longint; procedure merge(var a,b:map);
var
i,j,k:longint;
begin
fillchar(c,sizeof(c),);
for k:= to tot do
for i:= to tot do
for j:= to tot do
if c[i,j]>a[i,k]+b[k,j] then
c[i,j]:=a[i,k]+b[k,j];
a:=c;
end; procedure work;
begin
fillchar(g,sizeof(g),);
for i:= to tot do g[i,i]:=;
while n> do
begin
if n and = then merge(g,d);
merge(d,d);
n:=n>>;
end;
writeln(g[num[s],num[e]]);
end; begin
readln(n,t,s,e);
fillchar(d,sizeof(d),);
for i:= to t do
begin
readln(len,x,y);
if num[x]= then
begin
inc(tot);num[x]:=tot;
end;
if num[y]= then
begin
inc(tot);num[y]:=tot;
end;
d[num[x],num[y]]:=len;d[num[y],num[x]]:=len;
end;
work;
end.

最新文章

  1. 简单的例子了解自定义ViewGroup(一)
  2. 使用 expect 命令执行自动分发系统
  3. Atitit 常见的树形结构 红黑树 &#160;二叉树 &#160;&#160;B树 B+树 &#160;Trie树&#160;attilax理解与总结
  4. hdu 4496 (并差集)
  5. 在ecshop商品详情页显示供货商
  6. JavaScript之对象序列化详解
  7. DOM中元素对象的属性方法
  8. SpringMVC自定义配置消息转换器踩坑总结
  9. IntelliJ IDEA创建java项目
  10. 用C#语言编写:数组分析器
  11. python3爬虫之入门和正则表达式
  12. C# 添加Excel表单控件(Form Controls)
  13. node环境使用multer搭建一个图片接收服务器
  14. AJAX实现登陆
  15. 服务管理之rsync
  16. Codeforces Round #542 Div. 1
  17. Confluence 6 附件存储配置
  18. Java 构造器 遇到多个构造器时要考虑用构建器
  19. springboot-thymeleaf
  20. oracle 中decode函数用法

热门文章

  1. 聊聊Bug引发事故该不该追求责任
  2. Python字符串格式化符号及转义字符含义(非常全!!!)
  3. 【WXS数据类型】Object
  4. 基础的表ADT -数据结构(C语言实现)
  5. 饥饿的小易(枚举+广度优先遍历(BFS))
  6. phantomjs抛出IOException
  7. 条款02:尽量以const,enum,inline替换#define
  8. lintcode-18-带重复元素的子集
  9. osg::Vec2 Vec3 Vec4
  10. C# Winform防止闪频和再次运行