奶牛接力 矩阵乘法

题意/Description

       为增强体质,约翰决定举办一场奶牛接力跑比赛。比赛现场有一些接力位置,这些位置间有T条路连接,第i条路的长度为Li。 有N头奶牛需要参加比赛,领头的奶牛从位置S出发,她会按照你的指示沿着一条路跑到下个位置,把接力棒交给等在那里的下一头奶牛,就休息去了。每头奶牛重复这个过程这条接力路线的终点必须在位置E上。

       奶牛数量较多,允许一些奶牛等候在同一位置,一条路也可以供多头奶牛奔跑。 奶牛们对接力跑兴趣不大,拜托你敷衍地设计一条总长度最短的路线。所以请设计一条由N段路组成的,起点在S,终点在E上的最短路线吧。

 

读入/Input

       第一行:四个用空格分开的整数:表示N,T,S和E,2 ≤ N ≤ 106,2 ≤ T ≤ 100,1 ≤ S, E ≤ 1

       第二行到T + 1行: 第i + 1行首先有一个正整数Li,表示第i条路的长度, 1 ≤ Li ≤ 1,其次是Ui和Vi,表示第i条路连接的两个位置,1 ≤ Ui, Vi ≤ 1


输出/Output

       第一行:单个整数,表示起点为S,终点为E,且恰好经过N段路的最短路线长度


题解/solution

      题目似乎十分简单,用一个邻接矩阵A就OK,T也不大,但N却十分吓人惊恐,所以先离散化(1—1000),再建造。

       这题求的是恰好经过N段路的最短路线长度,即矩阵A[i,j]表示从点i到点j的最小值,显然不能和往常那样写c[i,j]=c[i,j]+a[i,k]*b[k,j]了。所以在矩阵乘法那改一下,c[i,j]:=min(c[i,j],a[i,k]+b[k,j])且(0<a[i,j],b[k,j])即可。

       最后在程序中注意一下矩阵的值的大小,否则很容易出错。惊讶

       

代码/Code

type
  arr=array [0..101,0..101] of longint;
var
  n,t,q,z,m:longint;
  d,c:arr;
  o:array [0..1001] of longint;
procedure mi(a,b:arr);
var
  i,j,k:longint;
begin
  for i:=1 to m do
    for j:=1 to m do
      c[i,j]:=maxlongint div 3;
  for i:=1 to m do
    for j:=1 to m do
      for k:=1 to m do
        if (a[i,k]<maxlongint) and (b[k,j]<maxlongint) then
          if a[i,k]+b[k,j]<c[i,j] then
            c[i,j]:=a[i,k]+b[k,j];
end;

procedure main(n:longint);
begin
  if n<=1 then exit;
  main(n div 2);
  mi(c,c);
  if odd(n) then mi(c,d);
end;

procedure init;
var
  x,y,t,l,i,j:longint;
begin
  readln(n,t,q,z);
  m:=0;
  for i:=1 to t do
    begin
      readln(l,x,y);
      if o[x]=0 then
        begin
          inc(m);
          o[x]:=m;
        end;
      if o[y]=0 then
        begin
          inc(m);
          o[y]:=m;
        end;
      d[o[x],o[y]]:=l;
      d[o[y],o[x]]:=l;
    end;
  for i:=1 to m do
    for j:=1 to m do
      if d[i,j]=0 then d[i,j]:=maxlongint;
  c:=d;
end;

begin
  init;
  main(n);
  write(c[o[q],o[z]]);
end.


  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值