【图论】【单源最短路】【dijikstra】pascal+邻接矩阵/边集数组

1.邻接矩阵

var  w:array[1..15000,1..15000] of -1..2;
    p:array[1..15000] of integer;
    i,n,m,t1,t2,t3,t:longint;
procedure dijik;
var i,j,minn,min:longint;
    d:array[1..15000] of longint;
    f:array[1..15000] of boolean;
begin   
    fillchar(f,sizeof(f),false);
    for i:=1 to n do if w[1,i]<>0 then d[i]:=w[1,i]  else d[i]:=maxlongint;
        minn:=1;
        f[1]:=true;
    d[1]:=0;
        for i:=1 to n-2 do begin
                min:=maxlongint;
                for j:=1 to n do
                if (d[j]<min) and (d[j]>0) and (not f[j]) then begin
                       minn:=j;
                       min:=d[j];
                end;
        f[minn]:=true;
        if min=maxlongint then exit;
                for j:=1 to n do if (w[minn,j]<>0) and (not f[j]) then
                if (min+w[minn,j]<d[j]) then begin
                        d[j]:=min+w[minn,j];
                        //p[j]:=minn;
                end;
        end;
        writeln(d[n]);
end;
begin
    readln(n,m);
    for i:=1 to m do begin
        readln(t1,t2,t3);
                w[t1,t2]:=t3;
    end;
    dijik;
end.

2.边集数组

ype     edge = record
        a,b:longint;
        w:-1..2;
    end;
var i,n,m:longint;
    num:array[0..300001] of longint;
    g:array[0..500001] of edge;
procedure sort(l,r:longint);
var i,j,x,y: longint;
begin
    i:=l;j:=r;x:=g[(l+r) div 2].a;
    repeat
        while g[i].a<x do inc(i);
        while x<g[j].a do dec(j);
            if not(i>j) then begin
                    y:=g[i].a;
                    g[i].a:=g[j].a;
                    g[j].a:=y;
            y:=g[i].b;
                    g[i].b:=g[j].b;
                    g[j].b:=y;
            y:=g[i].w;
                    g[i].w:=g[j].w;
                    g[j].w:=y;
                    inc(i);dec(j);
                end;
         until i>j;
         if l<j then sort(l,j);
         if i<r then sort(i,r);
end;
procedure dijik;
var i,j,min,minn:longint;
    d:array[0..300001] of int64;
    f:array[0..300001] of boolean;
    pre:array[0..300001] of longint;
function find(u,v:longint):longint;
var i:longint;
begin
    find:=0;
    for i:=pre[u] to pre[u+1]-1 do with g[i] do if b=v then find:=w;
end;
begin   
    for i:=1 to n do d[i]:=maxlongint;
    fillchar(f,sizeof(f),false);
    sort(1,m);
    pre[1]:=1;
    for i:=2 to n do pre[i]:=pre[i-1]+num[i-1];
    for i:=1 to pre[2]-1 do with g[i] do if w<>0 then d[b]:=w;
        minn:=1;f[1]:=true;d[1]:=0;
        for i:=1 to n-2 do begin
                min:=maxlongint;
                for j:=1 to n do
                if (d[j]<min) and (not f[j]) then begin
                       minn:=j;
                       min:=d[j];
                end;
        if min=maxlongint then exit;
        f[minn]:=true;
        for j:=1 to n do if not f[j] then begin
            t:=find(minn,j);
            if (t<>0) and (min+t<d[j]) then d[j]:=min+t;
        end;
        end;
        writeln(d[n]);
end;
begin
    readln(n,m);
    for i:=1 to m do with g[i] do readln(a,b,w);
    for i:=1 to m do with g[i] do inc(num[a]); 
    dijik;
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值