apio2009 atm題解

        題目請自行百度.

        這道題和sort很像,甚至比sort還水.在此再次吐槽noip模擬題的難度,完全跟noip不是一個級別.

        先縮點,求最長路即可.又打了一遍tarjan,應該不會忘了吧.

Code:

{$M 10000000}
program main;
type int=longint;
var
        i,j,k,m,n,high,ans:int;
        dis,low,dfn,h,tail,w,s,b,a:array[1..500000]of int;
        ne,t:array[1..500000]of int;
        x,y,tot:int;

function min(x,y:int):int;
begin
        if x<y then exit(x)else exit(y);
end;

procedure dfs(x:int);var i,j:int;
begin
        inc(high);a[high]:=x;
        dfn[x]:=high;low[x]:=dfn[x];
        b[x]:=10009;j:=h[x];
        while j<>0 do begin
                i:=t[j];
                if b[i]=0 then begin
                        dfs(i);low[x]:=min(low[x],low[i]);
                end else if b[i]=10009 then begin
                        low[x]:=min(low[x],dfn[i]);
                end;
                j:=ne[j];
        end;
        if low[x]=dfn[x]then begin
                for i:=low[x]to high do begin
                        s[a[i]]:=x;b[a[i]]:=8;a[i]:=0;
                end;
                high:=low[x]-1;
        end;
end;

function relax(x,y:int):boolean;
begin
        if dis[y]>=dis[x]+w[y]then exit(false);
        dis[y]:=dis[x]+w[y];exit(true);
end;

function spfa(ss:int):int;var l,r:int;
begin
        l:=0;r:=1;a[r]:=s[ss];
        dis[s[ss]]:=w[s[ss]];
        repeat
                inc(l);i:=a[l];
                j:=h[i];b[k]:=0;
                while j<>0 do begin
                        k:=t[j];
                        if(k<>i)and(relax(i,k))and(b[k]<>998)then begin
                                inc(r);a[r]:=k;b[k]:=998;
                        end;
                        j:=ne[j];
                end;
        until l=r;
end;

begin
        assign(input,'atm.in');reset(input);
        assign(output,'atm.out');rewrite(output);
        read(n,m);
        for i:=1 to m do begin
                read(x,y);inc(tot);
                if h[x]=0 then tail[x]:=tot;
                t[tot]:=y;ne[tot]:=h[x];h[x]:=tot;
        end;
        for i:=1 to n do read(w[i]);
        for i:=1 to n do if b[i]=0 then dfs(i);
        for i:=1 to m do t[i]:=s[t[i]];
        for i:=1 to n do if s[i]<>i then begin
                ne[tail[s[i]]]:=h[i];h[i]:=0;
                tail[s[i]]:=tail[i];w[s[i]]:=w[s[i]]+w[i];
        end;
        read(x);spfa(x);
        read(m);ans:=0;
        for i:=1 to m do begin
                read(x);
                if dis[s[x]]>ans then ans:=dis[s[x]];
        end;
        write(ans);
        close(input);close(output);
end.


發佈了45 篇原創文章 · 獲贊 5 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章