??xml version="1.0" encoding="utf-8" standalone="yes"?>
描述Q?/strong>在对于Q选一个图中结点ؓ根的DFS搜烦树中建立一个LAB数组与LOW数组QLAB数组存储个结点的~号QLOW数组存储各点及其子树的各l点能到辄最编L点的~号?br>
2 DFS(u)
3 LAB[u] = LOW[u] = lab++
4 for each (u, v) in E(G)
5 if LAB[v] is 0
6 DFS(v)
7 LOW[u] = min{LOW[u], LOW[v]}
8 else if v isnot parent of u
9 LOW[u] = min{LOW[u], LAB[v]}
W?行中Q如?u, v)是树边,则对v做深度优先搜索,q且LOW[u] = min{LOW[u], LOW[v]}Q如?u, v)是反向边Q则LOW[u] = min{LOW[u], LAB[v]}?/span>
三、割?br> 描述Q?/strong>当一个结点u是割Ҏ必满以下两个条件之一Q?br> 1Qu为根且至有两棵子树Q?br> 2Qu不ؓ根且存在一个u在深搜树中的子女v使得LOW[v] ≥ LAB[u]?br> CZQ?/strong>POJ 1523 解题报告?br>四、桥
描述Q?/strong>一条边e=(u, v)是桥Q当且仅当e为树枝边且LOW[v] > LAB[u]?br> CZQ?/strong>POJ 3352 解题报告?/span>
]]>
LCAQLeast Common AncestorsQ最q公q先)Q对于一|ҎT的Q意两个节点uQvQ求出LCA(T, u, v)Q即跟最q的节点xQ得x同时是u和v的祖先?br> 在线法Q用比较长的旉做预处理Q但是等信息充以后每次回答询问只需要用比较的旉?br> ȝ法Q先把所有的询问dQ然后一h所有询问回{完成?br> RMQQ给Z个数lAQ回{询问RMQ(A, i, j)Q即A[i...j]之间的最值的下标?br>二、DFS+RMQ
1QSparse TableQSTQ算?br> 描述Q?/strong>
分析Q?/strong>初始化过E实际上是一个动态规划的思想。易知,初始化过E效率是O(nlogn)Q而查询过E效率是O(1)。ST是一个在U算法?br> CZQ?/strong>POJ 3368 解题报告
2Q求解LCA问题
描述Q?/strong>
Q?QDFSQ从树T的根开始,q行深度优先遍历Qƈ记录下每ơ到辄点。第一个的l点是root(T)Q每l过一条边都记录它的端炏V由于每条边恰好l过2ơ,因此一p录了2n-1个结点,用E[1, ... , 2n-1]来表C?br> Q?Q计RQ用R[i]表示E数组中第一个gؓi的元素下标,卛_果R[u] < R[v]ӞDFS讉K的顺序是E[R[u], R[u]+1, ..., R[v]]。虽然其中包含u的后代,但深度最的q是u与v的公q先?br> Q?QRMQQ当R[u] ≥ R[v]ӞLCA[T, u, v] = RMQ(L, R[v], R[u])Q否则LCA[T, u, v] = RMQ(L, R[u], R[v])Q计RMQ?br> ׃RMQ中用的ST法是在U算法,所以这个算法也是在U算法?br> CZQ?/strong>ZOJ 3195 解题报告?br>三、Tarjan法
描述Q?/strong>Tarjan法是一个离U算法,也就是说只有先获得所有的查询Q再按一个特定的序q行q算?/p>
2 Tarjan(u)
3 visit[u] = true
4 for each (u, v) in QUERY
5 if visit[v]
6 ans(u, v) = FIND(v)
7 for each (u, v) in TREE
8 if !visit[v]
9 Tarjan(v)
10 parent[v] = u
]]>
最费用最大流Q设G是以s为源t为汇的网l,c是G的容量,b是G的单位流量费用,且有b[i][j] = -b[i][j]Qf是G的流Q则b(f)=?fij*bij)Q?i, j)∈E(G) 且fij>0。最费用最大流问题Q就是求|络G的最大流f且费用b(f)最。这L称为最费用最大流?/span>
二、算法思想
用Ford-Fulkerson法的思想Q不断地在残留网l中L增广路,只不q这个增q\是当前网l中s到t的以单位量费用为权的最短\Q对q条增广路进行操作。由于费用有负|用SPFA法?br>三、算法介l?br> 描述Q?/span>
说明Q?/strong>W?行的DFS(u)q程Q当存在从u开始的M可增q\Q则q回trueQƈ完成M的扩展,此时|M|加一。如果返回falseQ则表示不存在M可增q\?nbsp;
CZQ?/strong>POJ 1274 解题报告?/span>
三、最优匹配(KM法Q?br> 描述Q?/strong>
Q?Q从L可行标l开始,定l{子图GlQƈ且在Gl中选取匚wM。若M饱和V1Q则M是完匹配,也即M是最优匹配,法l止Q?br> Q?Q否则,q用匈牙利算法,l止于S属于V1QT属于V2且对于GlQN(S)=T。oal=min{l(x)+l(y)-w(x, y) | x∈S, y∈V2-T}Qol'(u)=l(u)-al如果u∈SQl'(u)=l(u)+al如果u∈TQl'(u)=l(u)Q其它。用l'代替lQ用Gl'代替Gl转入Q?Q?br> 实现Q?/strong>
网l:G=(V, E)是一个有向图Q其中每条边(u, v)∈E均有一个非负容?span lang="EN-US">c(u, v) ≤0Q否?span lang="EN-US">c(u, v)?span lang="EN-US">0.网l中有两个特别的点Q源?span lang="EN-US">s和汇?span lang="EN-US">t。对于每个顶?span lang="EN-US">v∈VQ都存在一条\?span lang="EN-US">s…v…t?span lang="EN-US">
:G上的一个实值函?span lang="EN-US">(V×V→R)Q满?span lang="EN-US">1)对于Lu, v∈VQ?span lang="EN-US">f(u, v)≤c(u, v)Q?span lang="EN-US">2)对于Lu, v∈VQ?span lang="EN-US">f(u, v)=-f(u, v)Q?span lang="EN-US">3)对于Lu∈V-{s, t}Q∑f(u, i)=0。定义流|f|=?span lang="EN-US">f(s, i)?span lang="EN-US">
D留|络Q给定流|络和一个流Q其D留|络由可以容Ux多网l流的边l成。定义残留容?span style="color: red;" lang="EN-US">cf(u, v)=c(u, v)-f(u, v)。残留网l?span lang="EN-US">Gf=(V,Ef),其中Ef={(u, v)∈V×V:cf(u, v)>0}?span lang="EN-US">
增广路径Q增光\?span lang="EN-US">p为残留网l?span lang="EN-US">Gf中从s?span lang="EN-US">t的一条简单\径?span lang="EN-US">
网l的Ԍ网l的?span lang="EN-US">(S, T)?span lang="EN-US">V划分?span lang="EN-US">S?span lang="EN-US">T=V-S两部分,使得s∈SQ?span lang="EN-US">t∈T。穿q割的净定义ؓf(S, T)Q且?span lang="EN-US">f(S, T)=|f|。割的容量ؓc(u, v)。一个网l的最割是|络中所有割中流量最的剌Ӏ?span lang="EN-US">
最大流最割定理Q以下三个条件等P1)f?span lang="EN-US">G的一个最大流Q?span lang="EN-US">2)D留|络Gf不包含增q\径;3)?span lang="EN-US">G的某个割(S, T)Q有|f|=c(S, T)?span lang="EN-US">
前置:是一个函?span lang="EN-US">fQ?span lang="EN-US">V×V→RQ它满1)对于Lu, v∈VQ?span lang="EN-US">f(u, v)≤c(u, v)Q?span lang="EN-US">2)对于Lu, v∈VQ?span lang="EN-US">f(u, v)=-f(u, v)Q?span lang="EN-US">3)对于Lu∈V-{s, t}Q?span lang="EN-US">f[V, u]≥0。定义余?span lang="EN-US">e[u]=f[V, u]Q对?span lang="EN-US">u∈V-{s, t}Q当e[u]>0ӞU顶?span lang="EN-US">u溢出?span lang="EN-US">
高度函数Q函?span lang="EN-US">hQ?span lang="EN-US">V→N满h[s]=|V|Q?span lang="EN-US">h[t]=0Q且Ҏ条残留边(u, v)∈EfQ有h[u]≤h[v]+1?span lang="EN-US">
容许边:如果cf(u, v)>0?span lang="EN-US">h[u]=h[v]+1Q则U?span lang="EN-US">(u, v)是容许边。否则,(u, v)是非容许辏V容许网lؓGf,h=(V, Ef,h)Q其?span lang="EN-US">Ef,h为容许边的集合。根据容许边有关高度的定义,易知Q容许网l不存在回\?br>
二?nbsp; Ford-FulkersonҎ
1Q?nbsp;基本的Ford-Fulkerson法
描述Q?/strong>
分析Q?/strong>Ford-Fulkersonq程的效率取决于如何定增广路径。如果选择不好Q对于非有理的容量,法有可能不能终止。如果容量是整数Q如果容量不是整敎ͼ可以乘以特定的因子{化ؓ整数Q。这ӞW?~4行运行时间ؓO(E),W?~9行,while循环臛_执行|f*|Q这是因为在每次q代后,D增?。故法效率为O(E|f*|)。当最大流f*较小Ӟq个法的效率还是不错的?/span>
2QEdmonds-Karp法
描述Q?/strong>基本的Ford-Fulkerson法的第5行中用广度优先搜索来实现增广路p的计,卛_q\径是D留|络中从s到t的最短\?其中每条边ؓ单位距离或权)Q则能够改进Ford-Fulkerson法的界?br> 分析Q?/strong>随着法的运行,对于所有顶点v∈V-{s, t}Q残留网lGf中的最短\径长?#948;f(s, v)随着每个的增加而单调递增。直观看来,每次增加的操作都将使得当前最短\中的一条边(卛_键边Qcf(a, b)=cf(p))从p中消失,从而得新生成的Gf中的最短\径的长度增加。同ӞL?u, v)臛_能成为|V|/2-1ơ成为关键边。这是因为第iơ成为关键边时有δf(s, v)=δf(s, u)+1Q而第i+1ơ时f[u, v]只可能与上次异号Q则?#948;f'(s, u)=δf'(s, v)+1Q且?#948;f'(s, v)≥δf(s, v)Q则δf'(s, u)=δf'(s, v)+1)≥δf(s, v)+1=δf(s, u)+2。故(u, v)每次成ؓ关键辚w?#948;f(s, u)增加2Q有׃δf(s, u)最大gؓ|V|-2Q则L?u, v)臛_能成为|V|/2-1ơ成为关键边。故该算法的旉复杂性ؓO(VE2)?br> CZQ?/strong>POJ 1273 解题报告
三?nbsp; Push-Relabel法
描述Q?/strong>
正确性:用@环不变式来说?br> 1Q初始化QINITILIZATION-FREFLOW初始化f为前|流
2Q保持:法中只使用了push与relabel操作Qrelabel操作只媄响高度,不媄响fQ而push(u, v)操作Q只会增加点v的流入量即f(V, v)Q?br>所以如果操作以前是前置,操作后还是前|流
3Q终止:在终止时QV-{s, t}中的每个点的余必?Q如果存在不?的点Q则必可以进行push或relabel操作Q,且最l得到的是一个前|流Q故最l得到的是一个流。又在最l的D留|络中,不存在s到t的\径(否则Q如存在一条\径s,v1,...,tQ则s可以向压入流Q得v1溢出Q,Ҏ最大流最割定理Qf是最大流?br> 分析Q?/strong>首先Q证明对于Q意溢出点uQ均存在一条在Gf上的u到s的\Q设U={v|在Gf存在一条s到v的\径}Q设U#=V-UQ假设s不属于UQ对于顶点对(v, w)Qv属于UQw属于U#Q有f(v, w)≤0Q否则,如果f(v, w)>0Q则有cf(v, w)=c(v, w)-f(v, w)=c(v, w)+f(w, v)>0Q这与w不属于U矛盾Qe[u] =f(V, U)=F(U, U)+f(U#, U)=F(U#, U)≤0Q而对于v∈V-{s}Qe[v]≥0Q又e[u]>0Q则U中必有sQ矛盾!
relabel操作Q对于源点与会点Q不存在relabel操作Q而对于其它顶点uQ初始时Qh[u]=0≤2|V|-1Q当uq行relabelӞu溢出Q则Gf中必存在一条u到s的\径p=<u=v0,v1,...,vk=s>Q由高度函数的定?u, v)∈EfQ有h[u]≤h[v]+1Q则h[u]=h[v0]≤h[vk]+k≤h[s]+|V|-1=2|V|-1Q算法中d的relabel操作ơ数为O(V2)?br> 饱和push操作Q进行操作后Q?u, v)边从Ef中消失,则称该push操作为饱和push操作Q进行一?u, v)的饱和push操作必有h[u]=h[v]+1Q同Ӟ要进行下一?u, v)的饱和push操作Q必先经q一?v, u)的饱和push操作Q则两次饱和操作室h[u]增加2Q又h[u]≤2|V|-1Q则每个点臛_q行|V|ơ饱和push操作Q则d的饱和push操作ơ数为O(|V||E|)?br> 不饱和push操作Qpush操作中除去饱和push操作Q剩下的是不饱和push操作。定义一个函数gQgؓ所有e值大?的顶点的高度和,故g≥0。考察三种操作对g值的影响Q?Qrelabel操作不会改变溢出性且只会改变一个点Q而一个点的变化至多ؓ2|V|-1Q则g臛_增加2|V|-1Q?Q饱和push操作可能能增加一个溢出点Qg臛_增加2|V|-1Q?Q不饱和push(u, v)操作会u变ؓ不溢出,而在v从不溢出到溢出时Q减的最,?Q因为h[u]=h[v]+1)。则不饱和push操作的次数至多ؓO(|V|2|E|+|V|3)?br> lgQPush-Relabel法是正的且效率ؓO(V2E)?br> CZQ?/strong>POJ 1459 解题报告
一?单个点到图中各个点的距离
二?图中L两个点之间的距离
Bellman-Ford法与另一个非常著名的Dijkstra法一P用于求解单源Ҏ短\径问题?/span>Bellman-ford法除了可求解边权均非负的问题外Q还可以解决存在负权边的问题Q意义是什么,好好思考)Q?/span>Dijkstra法只能处理Ҏ非负的问题,因此 Bellman-Ford法的适用面要q泛一些。但是,原始?/span>Bellman-Ford法旉复杂度ؓ OQ?/span>VEQ?/span>,?/span>Dijkstra法的时间复杂度高,所以常常被众多的大学算法教U书所忽略Q就q经典的《算法导论》也只介l了基本?/span>Bellman-Ford法Q在国内常见的基本信息学奥赛教材中也均未提及Q因此该法的知名度与被掌握度都不如Dijkstra法。事实上Q有多种形式?/span>Bellman-Ford法的优化实现。这些优化实现在旉效率上得到相当提升,例如q一两年被热捧的SPFAQ?/span>Shortest-Path Faster Algoithm 更快的最短\径算法)法的时间效率甚至由?/span>Dijkstra法Q因此成Z息学奥赛选手l常讨论的话题。然而,限于资料匮乏Q有?/span>Bellman-Ford法的诸多问题常常困扰奥赛选手。如Q该法值得掌握么?怎样用编E语a具体实现Q有哪些优化Q与SPFA法有关pMQ本文试囑֯Bellman-Ford法做一个比较全面的介绍。给出几U实现程序,从理论和实测两方面分析他们的旉复杂度,供大家在备战省选和后箋?/span>noi时参考?/span>
Bellman-Ford法能在更普遍的情况下(存在负权边)解决单源Ҏ短\径问题。对于给定的带权Q有向或无向Q图 G=Q?/span>V,EQ,其源点ؓsQ加权函?/span> w?/span> 辚w E 的映。对?/span>Gq行Bellman-Ford法的结果是一个布|表明图中是否存在着一个从源点s可达的负权回路?/span>若不存在q样的回路,法给Z源点s?/span> ?/span>G的Q意顶?/span>v的最短\?/span>d[v]?/span>
Q?Q?span style="FONT: 7pt Times New Roman; font-size-adjust: none; font-stretch: normal"> 初始化:除源点外的所有顶点的最短距M计?/span> d[v] ←+∞, d[s] ←0;
Q?Q?span style="FONT: 7pt Times New Roman; font-size-adjust: none; font-stretch: normal"> q代求解Q反复对辚wE中的每条边进行松弛操作,使得点集V中的每个点v的最短距M计值逐步D其最短距;Q运行|v|-1ơ)
Q?Q?span style="FONT: 7pt Times New Roman; font-size-adjust: none; font-stretch: normal"> 验负权回路:判断辚wE中的每一条边的两个端Ҏ否收敛。如果存在未收敛的顶点,则算法返?/span>falseQ表明问题无解;否则法q回trueQƈ且从源点可达的顶?/span>v的最短距M存在 d[v]中?/span>
法描述如下Q?/span>
Bellman-Ford(G,w,s) Q?/span>boolean //?/span>G Q边?/span> 函数 w Q?/span>s为源?/span>
1 for each vertex v ∈ VQGQ?do //初始?span> 1阶段
2 d[v] ←+∞
3 d[s] ←0; //1阶段l束
4 for i=1 to |v|-1 do //2阶段开始,双重循环?/span>
5 for each edgeQu,vQ?∈E(G) do //辚w数组要用刎ͼID每条辏V?/span>
6 If d[v]> d[u]+ w(u,v) then //村ּ判断
7 d[v]=d[u]+w(u,v) //村ּ操作 2阶段l束
8 for each edgeQu,vQ?∈E(G) do
9 If d[v]> d[u]+ w(u,v) then
10 Exit false
11 Exit true
下面l出描述性证明:
首先指出Q图的Q意一条最短\径既不能包含负权回\Q也不会包含正权回\Q因此它最多包?/span>|v|-1条边?/span>
其次Q从源点s可达的所有顶点如?/span> 存在最短\径,则这些最短\径构成一个以s为根的最短\径树?/span>Bellman-Ford法的P代松弛操作,实际上就是按点距离s的层ơ,逐层生成q棵最短\径树的过E?/span>
在对每条边进?span>1 遍松弛的时候,生成了从s出发Q层ơ至多ؓ1的那些树枝。也是_扑ֈ了与s臛_?条边相联的那些顶点的最短\径;Ҏ条边q行W?遍松弛的时候,生成了第2层次的树枝,是说找Cl过2条边相连的那些顶点的最短\?#8230;…。因为最短\径最多只包含|v|-1 条边Q所以,只需要@环|v|-1 ơ?/span>
每实施一ơ松弛操作,最短\径树上就会有一层顶点达到其最短距,此后q层点的最短距d就会一直保持不变,不再受后l松弛操作的影响。(但是Q每ơ还要判断松弛,q里费了大量的旉Q怎么优化Q单U的优化是否可行Q)
如果没有负权回\Q由于最短\径树的高度最多只能是|v|-1Q所以最多经q|v|-1遍松弛操作后Q所有从s可达的顶点必求出最短距R如?d[v]仍保?+∞Q则表明从s到v不可达?/span>
如果有负权回路,那么W?span> |v|-1 遍松弛操作仍然会成功Q这Ӟ负权回\上的点不会收敛?/span>
例如对于上图Q边上方框中的数字代表权|点A,B,C之间存在负权回\。S是源点,点中数字表C行Bellman-Ford法后各点的最短距M计倹{?/span>
此时d[a] 的gؓ1Q大于d[c]+w(c,a)的?2Q由此d[a]可以村ּ?2Q然后d[b]又可以松弛ؓ-5,d[c]又可以松弛ؓ-7.下一个周期,d[a]又可以更Cؓ更小的|q个q程永远不会l止。因此,在P代求解最短\径阶D늻束后Q可以通过验边集E的每条边(u,v)是否满关系?span> d[v]> d[u]+ w(u,v) 来判断是否存在负权回路?/span>
?/span> bellmanford.pas 文g
分析 Bellman-Ford法Q不隄出,外层循环QP代次敎ͼ|v|-1实际上取得是上限。由上面对算法正性的证明可知Q需要的q代遍数{于最短\径树的高度。如果不存在负权回\Q^均情况下的最短\径树的高度应该远q小?/span> |v|-1Q在此情况下Q多余最短\径树高的q代遍数是旉上的费Q由此,可以依次来实施优化?/span>
从细节上分析Q如果在某一遍P代中Q算法描qCW?/span>7行的村ּ操作未执行,说明该遍q代所有的辚w没有被松弛。可以证明(怎么证明Q)Q至此后Q边集中所有的辚w不需要再被松弛,从而可以提前结束P代过E。这P优化的措施就非常单了?/span>
讑֮一个布型标志变量 relaxedQ初gؓfalse。在内层循环中,仅当有边被成功松弛时Q将 relaxed 讄?/span>true。如果没有边被松弛,则提前结束外层@环。这一改进可以极大的减外层@环的q代ơ数。优化后?/span> bellman-ford函数如下?/span>
function bellmanford(s:longint):boolean;
begin
for i:=1 to nv do
d[i]:=max;
d[s]:=0;
for i:=1 to nv-1 do
begin
relaxed:=false;
for j:=1 TO ne do
if(d[edges[j].s]<>max) and (d[edges[j].e]>d[edges[j].s]+edges[j].w)
then begin
d[edges[j].e]:=d[edges[j].s]+edges[j].w ;
relaxed:=true;
end;
if not relaxed then break;
end;
for i:=1 to ne do
if d[edges[j].e]>d[edges[j].s]+edges[j].w then exit(false);
exit(true);
end;
q样看似q_的优化,会有怎样的效果呢Q有研究表明Q对于随机生成数据的q_情况Q时间复杂度的估公式ؓ
1.13|E| if |E|<|V|
0.95*|E|*lg|V| if |E|>|V|
优化后的法在处理有负权回\的测试数据时Q由于每ơ都会有边被村ּQ所?/span>relaxed每次都会被置?/span>trueQ因而不可能提前l止外层循环。这对应了最坏情况,其时间复杂度仍旧?/span>O(VE)?/span>
优化后的法的时间复杂度已经和用二叉堆优化的Dijkstra法相近了,而编码的复杂E度q比后者低。加?/span>Bellman-Ford法能处理各U边值权情况下的最短\径问题,因而还是非怼U的?/span>Usaco3.2.6 的程序见bellmanford_1.pas
四?/span>SPFA 法
SPFA是目前相当优U的求最短\径的法Q值得我们掌握?/span>
SPFA?/span>Bellman-Ford法优化的关键之处在于意识到Q?span style="COLOR: #ff6600">只有那些在前一遍松弛中改变了距M计值的点,才可能引起他们的L点的距离估计值的改变?/span>因此Q用一个先q先出的队列来存放被成功村ּ的顶炏V初始时Q源?/span>s入队。当队列不ؓI时Q取出对首顶点,对它的邻接点q行村ּ。如果某个邻接点村ּ成功Q且该邻接点不在队列中,则将其入队。经q有限次的松弛操作后Q队列将为空Q算法结束?/span>SPFA法的实玎ͼ需要用C个先q先出的队列 queue 和一个指C顶Ҏ否在队列中的 标记数组 mark。ؓ了方便查找某个顶点的L点,N用界表存储?/span>
E序存储?/span> spfa.pas中。以usaco 3.2.6 试题2Z。用L表写的程序?/span>
需要注意的是:仅当图不存在负权回\ӞSPFA能正常工作。如果图存在负权回\Q由于负权回路上的顶Ҏ法收敛,L点在入队和出队往q,队列无法为空Q这U情况下SPFA无法正常l束?/span>
判断负权回\?/span>Ҏ很多Q世间流传最q的是记录每个结点进队次敎ͼ过|V|ơ表C有负权
q有一U方法ؓ记录q个l点在\径中处于的位|,ord[i]Q每ơ更新的时?/span>ord[i]=ord[x]+1Q若过|V|则表C有负圈.....
其他Ҏq有很多Q我反倒觉得流传最q的Ҏ是最慢的.......
关于SPFA的时间复杂度Q不好准估计,一般认为是 OQ?/span>kEQ,k是常?/span>
上述介绍?/span>Bellman-Ford法及两U的优化Q只是在理论上分析了旉复杂度,用实际的数据试Q会有什么结果呢Qؓ此,我们选择 usaco 3.2.6?/span>
Spfa的时间效率还是很高的。ƈ?/span>spfa的编E复杂度要比Dijksta+heap优化要好的多?/span>
l过优化Bellman-Ford法是非怼化的求单源最短\径的法Q?/span>SPFA旉效率要优于第一U优化Ş式,但第一U优化Ş式的~码复杂度低?/span>SPFA。两U优化Ş式的~程复杂度都低于Dijkstra法。如果在判断是否存在负权回\Q推荐用第一U优化Ş式,否则推荐使用SPFA?/span>