最短路+网络流/sgu 185 Two shortest
2013-03-21 21:50
225 查看
[b]题意[/b]
求一个无向图中没有重边的两条最短路,并输出方案
[b]分析[/b]
注意,是两条最短路!不是一条最短一条次短!所以先来个dijkstra/spfa来算一下最短路
根据dijkstra/spfa求出的dist[i]数组,建立一个新图,上面只有所有满足最短路的边构成的图
这样,建图就Ok了,下面如何解决没有重边呢?
很显然,设立一个源点和汇点,在源点出放出2的值。然后把刚刚建好的新图,边的权值设为1,相当于只能允许一个人经过。这样,如果在汇点得到了2的值,说明这样的两条路是存在的,再利用一个dfs求出即可。
注意dinic需要加上当前弧优化,不然会tle at #17
[b]Accepted Code[/b]
求一个无向图中没有重边的两条最短路,并输出方案
[b]分析[/b]
注意,是两条最短路!不是一条最短一条次短!所以先来个dijkstra/spfa来算一下最短路
根据dijkstra/spfa求出的dist[i]数组,建立一个新图,上面只有所有满足最短路的边构成的图
这样,建图就Ok了,下面如何解决没有重边呢?
很显然,设立一个源点和汇点,在源点出放出2的值。然后把刚刚建好的新图,边的权值设为1,相当于只能允许一个人经过。这样,如果在汇点得到了2的值,说明这样的两条路是存在的,再利用一个dfs求出即可。
注意dinic需要加上当前弧优化,不然会tle at #17
[b]Accepted Code[/b]
{ PROBLEM:sgu185 AUTHER:Rinyo MEMO:最短路 网络流 } Program sgu185; Const Infile = 'sgu185.in'; Outfile = ''; Type Rec = Record y,s,flow:Longint; End; Var map:Array[0..160000]Of REc; a:Array[0..430,0..430]Of Longint; dist,q,num,next,p:Array[0..430]Of Longint; v:Array[0..430]Of Boolean; maxflow,i,j,n,m,l:Longint; flag:Boolean; Function min(a,b:Longint):Longint; Begin if a<b Then min:=a Else min:=b; End; Procedure init; Var x,y,w:Longint; Begin ReadLn(n,m); For i:=1 To m Do Begin ReadLn(x,y,w); a[x,y]:=w; a[y,x]:=w; End; End; Procedure dijkstra; Var j,k,mink:Longint; begin Fillchar(dist,sizeof(dist),100); dist[1]:=0; For i:=1 To n-1 Do Begin mink:=maxlongint; For j:=1 To n Do If (not v[j]) And (dist[j]<mink) Then Begin mink:=dist[j]; k:=j; End; v[k]:=true; For j:=1 To n Do If (a[k,j]>0) And (dist[j]>mink+a[k,j]) Then dist[j]:=mink+a[k,j]; End; End; Function dfs(now,value:Longint):Longint; Var v1,i,x,ff:Longint; begin if now=n Then Begin dfs:=value; Exit; End; v1:=value; ff:=p[now]; While ff>-1 Do Begin i:=map[ff].y; If (map[ff].flow>0) And (num[i]=num[now]+1) Then begin x:=dfs(i,min(value,map[ff].flow)); map[ff].flow:=map[ff].flow-x; value:=value-x; If odd(ff) Then map[ff+1].flow:=map[ff+1].flow+x Else map[ff-1].flow:=map[ff-1].flow+x; End; ff:=map[ff].s; If value=0 then break; End; p[now]:=ff; dfs:=v1-value; End; Procedure bfs; Var head,tail,now,ff,v:Longint; Begin Fillchar(q,sizeof(q),0); Fillchar(num,sizeof(num),0); head:=0;tail:=1;q[1]:=1;num[1]:=1;flag:=false; While head<tail Do begin Inc(head); now:=q[head]; ff:=next[now]; While ff<>-1 Do Begin v:=map[ff].y; If (map[ff].flow>0) And (num[v]=0) Then Begin num[v]:=num[now]+1; Inc(tail); q[tail]:=v; If v=n Then Begin flag:=true; Exit; End; End; ff:=map[ff].s; End; End; End; Procedure answer(x:Longint); Var ff,v:Longint; Begin If (x=n) Then Begin WriteLn(n); Exit; End; ff:=next[x]; While ff<>-1 Do Begin v:=map[ff].y; If (map[ff].flow=0) And (a[x,v]+dist[x]=dist[v]) Then begin Write(x,' '); answer(v); map[ff].flow:=1; Exit; End; ff:=map[ff].s; End; End; Begin Assign(input,infile);Reset(input); Assign(output,outfile);Rewrite(output); init; dijkstra; l:=0; Fillchar(next,sizeof(next),$ff); For i:=1 To n Do For j:=1 To n Do If (i<>j) And (a[i,j]>0) Then If dist[i]+a[i,j]=dist[j] Then Begin Inc(l);map[l].y:=j;map[l].flow:=1;map[l].s:=next[i];next[i]:=l; Inc(l);map[l].y:=i;map[l].flow:=0;map[l].s:=next[j];next[j]:=l; End; flag:=true; While flag Do Begin BFS; p:=next; maxflow:=maxflow+dfs(1,2); End; //WriteLn(maxflow); If maxflow<2 Then Begin WriteLn('No solution'); End Else Begin answer(1); answer(1); End; Close(input);Close(output); End.
相关文章推荐
- SGU 185 Two shortest ★(最短路+网络流)
- SGU 185 Two shortest ★(最短路+网络流)
- sgu 185 Two shortest
- SGU 185 Two shortest
- SGU185 - Two Shortest
- SGU 185 Two shortest
- 解题报告 之 SGU185 Two shortest
- SGU 185 Two shortest 网络流+spfa+省内存
- SGU 185 Two shortest
- The Shortest Path in Nya Graph HDU - 4725(最短路,spfa)
- HDU 1595 find the longest of the shortest 【枚举删边 + 最短路】
- hdu 1595 find the longest of the shortest (枚举+最短路)
- Two shortest
- HDOJ 题目1595 find the longest of the shortest(枚举,最短路记录路径)
- HDOJ1595 find the longest of the shortest 最短路+枚举
- SGU 185 Two shortest(最短路+最大流)
- HDU 4725-J - The Shortest Path in Nya Graph-增点建图-层次网络-最短路
- zoj 2760 How Many Shortest Path 【最短路 + 最大流】 【求边不重复最短路径条数】
- HDU1595 find the longest of the shortest[最短路]
- sgu 185 Two shortest(最短路+最大流)