隊爺的講學計畫 (強連通縮點 最短路)

2021-07-24 08:09:09 字數 3811 閱讀 9794

隊爺的講學計畫

【問題描述】

隊爺為了造福社會,準備到各地去講學。他的計畫中有n個城市,從u到v可能有一條單向道路,通過這條道路所需費用為q。當隊爺在u城市講學完之後,u城市會派出一名使者與他同行,只要使者和他在一起,他到達某個城市就只需要花1的入城費且只需交一次,在路上的費用就可免去。。但是使者要回到u城市,所以使者只會陪他去能找到回u城市的路的城市。。隊爺從1號城市開始講學,若他在u號城市講學完畢,使者會帶他盡可能多的去別的城市。他希望你幫他找出一種方案,使他能講學到的城市盡可能多,且費用盡可能小。

【輸入檔案】

第一行2個整數n,m。

接下來m行每行3個整數u,v,q,表示從u到v有一條長度為q

的單向道路。

【輸出檔案】

一行,兩個整數,為最大講學城市數和最小費用。

【輸入樣例】

6 6

1 2 3

2 3 7

2 6 4

3 4 5

4 5 4

5 2 3

【輸出樣例】

6 10

【樣例解釋】

如上圖,從1走到2,2城市使者會帶他到3,4,5城市,

回到2城市,再走到6,總費用為3+3+4=10。

【資料規模與約定】

對於20%的資料,1<=n<=20;

對於另外10%的資料,城市網路為一條單向鏈;

對於60%的資料,1<=m<=200000

對於100%的資料,1<=n<=100000

1<=m<=500000,1<=q<=1000, 保證無自環無重邊。

**如下

program mys;

type ab=^node;

node=record

data,ends:longint;

next:ab;

end;

var x,y,z,i,j,k,m,n,t,ans,an:longint;

f,dis,g,hh:array[0..500000]of longint;

p,pa:array[0..500000]of ab;

team:array[0..5000000]of longint;

b,zhan:array[0..500000]of boolean;

ii:ab;

function

find

(x:longint):longint;

begin

if f[x]<>x then f[x]:=find(f[x]);

exit(f[x]);

end;

procedure

com(x,y,z:longint);

var i:ab;

begin

i:=p[x];

new(p[x]);

p[x]^.ends:=y;

p[x]^.data:=z;

p[x]^.next:=i;

end;

procedure

combine

(x,y,z:longint);

var i:ab;

begin

i:=pa[x];

new(pa[x]);

pa[x]^.ends:=y;

pa[x]^.data:=z;

pa[x]^.next:=i;

end;

procedure

dfs(x:longint);

var

y:longint;

i:ab;

begin

inc(t);

team[x]:=t;

b[x]:=true;

zhan[x]:=true;

i:=p[x];

while i<>nil

dobegin

y:=i^.ends;

ifnot b[y] then dfs(y);

y:=find(y);

if (zhan[y])and(team[x]>team[y]) then

begin

team[x]:=team[y];

f[x]:=y;

end;

i:=i^.next;

end;

zhan[x]:=false;

end;

procedure

spfa;

var t,x,h,u,y:longint;

i:ab;

begin

fillchar(b,sizeof(b),false);

fillchar(dis,sizeof(dis),$7f);

fillchar(team,sizeof(team),0);

t:=1; h:=0; team[1]:=1; b[1]:=true; hh[1]:=g[1]; dis[1]:=g[1]-1;

while hdo

begin

inc(h);

u:=team[h];

i:=pa[u];

b[u]:=false;

while i<>nil

dobegin

y:=i^.ends;

if (hh[y]or((hh[y]=hh[u]+g[y])and(dis[y]>dis[u]+i^.data+g[y]-1)) then

begin

hh[y]:=hh[u]+g[y];

dis[y]:=dis[u]+i^.data+g[y]-1;

if b[y]=false

then

begin

inc(t);

team[t]:=y;

b[y]:=true;

end;

end;

i:=i^.next;

end;

end;

end;

begin

assign(input,'teach.in');reset(input);

assign(output,'teach.out'); rewrite(output);

readln(n,m);

for i:=1

to m do

begin

readln(x,y,z);

com(x,y,z);

end;

for i:=1

to n do

f[i]:=i;

dfs(1);

for i:=1

to n do

inc(g[find(i)]);

for i:=1

to n do

begin

ii:=p[i];

x:=find(i);

while ii<>nil

dobegin

if find(ii^.ends)<>x then combine(x,find(ii^.ends),ii^.data);

ii:=ii^.next;

end;

end;

spfa;

ans:=maxlongint;

an:=0;

for i:=1

to n do

if (anor((an=hh[i])and(ans>dis[i])) then

begin

an:=hh[i];

ans:=dis[i];

end;

writeln(an,' ',ans);

close(input);

close(output);

end.

強連通縮點 最長路 搶掠計畫

搶掠計畫 siruseri城中的道路都是單向的。不同的道路由路口連線。按照法律的規定,在每個路口都設立了乙個 siruseri 銀行的 atm 取款機。令人奇怪的是,siruseri 的酒吧也都設在路口,雖然並不是每個路口都設有酒吧。banditji 計畫實施 siruseri有史以來最驚天動地的 ...

模板 強連通縮點

直接給他縮點然後求新的圖的完整版 c2 u 表示縮點後的u點這個環上的點實際上是哪些 g3 u 表示縮點後的u點的出邊 還是一樣,要記得先處理入鏈。可以讓這個圖好看一點但是沒啥鳥用 入鏈可能會有一些特別的性質,當然假如入鏈沒有特別性質也可以直接縮點。不對其實直接縮點就可以了,入鏈還是新圖的入鏈,環是...

hdu 2767 強連通縮點

補最少的邊成強連通圖。縮點後成dag,max即為所求。include include include define mn 20020 define me 200010 define mm a,b as void add e int i,int u,int v void tarjan int i el...