题解 P1576 【最小花费】

嘛,其实是一道dijkstra果题,pascal题解少了点,我也来水一水

$Round 1$ 作死

这道NOIp模拟题,我记得我做过吧,用dijkstra过十分之简单

于是乎,我抱着试一试de心态——用floyed做一做

floyed的效率大概是 $O(n^3)$ 由于是无向图所以可以优化为 $O(n^2*n/2)$

变形嘛,改一改就好

于是乎:

        for k:=1 to n do
        Begin
                for i:=1 to n do
                Begin
                        for j:=1 to i do
                        Begin
                                if w[i,k]*w[k,j]>w[i,j] then
                                Begin
                                        w[i,j]:=w[i,k]*w[k,j];
                                        w[j,i]:=w[i,j];
                                end;
                        end;
                end;
        end;

floyed就如此完成

结果……全部TLE

超了2000毫秒ヾ(≧へ≦)〃可恶至极

(我不会说就算用了dijkstra也是可耻的慢(毕竟没有堆优化))

上TLE程序:

Var n,m,i,j,k,x,y,z,a,b:longint;
    w:array[0..2003,0..2003] of double;
Begin
        readln(n,m);
        for i:=1 to m do
        Begin
                readln(x,y,z);
                w[x,y]:=(100-z)/100;
                w[y,x]:=w[x,y];
        end;
        readln(a,b);

        for k:=1 to n do
        Begin
                for i:=1 to n do
                Begin
                        for j:=1 to i do
                        Begin
                                if w[i,k]*w[k,j]>w[i,j] then
                                Begin
                                        w[i,j]:=w[i,k]*w[k,j];
                                        w[j,i]:=w[i,j];
                                end;
                        end;
                end;
        end;

        write(100/w[a,b]:0:8);
end.

$Round 2$ 正经八百地解题

当然是写了dijkstra,说实话我很不理解那些非要写SPFA的大佬,又木有负权回路干什么那么麻烦,写个Bellman-ford还非要加什么队列优化

以上为个人观点不喜勿喷,可以当没看到

dijkstra核心程序:

        repeat
                min:=0;
                for i:=1 to n do
                Begin
                        if (f[i]=false) and (w[a,i]>min) then
                        Begin
                                pos:=i;
                                min:=w[a,i];
                        end;
                end;        
                f[pos]:=true;
                for j:=1 to n do
                Begin
                        if (f[j]=false) and (w[a,pos]*w[pos,j]>w[a,j]) then
                        Begin
                                w[a,j]:=w[a,pos]*w[pos,j];
                                //w[j,a]:=w[a,j];
                        end;
                end;
                k:=k+1;
        until k=n-1;

别问为什么我的蜜汁码风如此独特

其实就是果题,不过需要改动的地方嘛,就是更新权值的部分。

由于是税率,所以不用加用乘,并且打折嘛,肯定是越多越好。

好的上AC代码:

Var n,m,i,j,k,x,y,z,a,b,pos:longint;
    min:double;
    w:array[0..2003,0..2003] of double;
    f:array[0..2003] of boolean;
Begin
        readln(n,m);
        for i:=1 to m do
        Begin
                readln(x,y,z);
                w[x,y]:=(100-z)/100;
                w[y,x]:=w[x,y];
        end;
        readln(a,b);

        f[a]:=true;
        repeat
                min:=0;
                for i:=1 to n do
                Begin
                        if (f[i]=false) and (w[a,i]>min) then
                        Begin
                                pos:=i;
                                min:=w[a,i];
                        end;
                end;        
                f[pos]:=true;
                for j:=1 to n do
                Begin
                        if (f[j]=false) and (w[a,pos]*w[pos,j]>w[a,j]) then
                        Begin
                                w[a,j]:=w[a,pos]*w[pos,j];
                                //w[j,a]:=w[a,j];
                        end;
                end;
                k:=k+1;
        until k=n-1;

        write(100/w[a,b]:0:8);
end.

希望能够给予您一点帮助

猜你喜欢

转载自blog.csdn.net/cpongo11/article/details/99674870
今日推荐