[题集]图论
生成樹
MST?Kruskal過(guò)程:貪心、重構(gòu)樹
prufer序列:一般樹,森林,有根樹,用于DP或者打暴力
Matrix-Tree定理:給定圖求生成樹個(gè)數(shù),鄰接矩陣數(shù)字表示邊權(quán)
多次求MST或者多次加邊等等:考慮縮點(diǎn)
一些圖的問(wèn)題:找到生成樹處理(如Tarjan的dfs樹,支配樹,最短路樹)
1.[Ctsc2014]圖的分割?
考慮Kruskal的過(guò)程,發(fā)現(xiàn)恰好可以直接貪心!
2.51Nod1446?限制價(jià)值樹?
兩部分,折半枚舉合法集合,統(tǒng)計(jì)生成樹個(gè)數(shù)
3.
最小生成樹計(jì)數(shù):排序kruskal時(shí)候,縮點(diǎn)配合矩陣樹
4.[APIO2013]道路費(fèi)用?
還是枚舉哪些邊會(huì)最終貢獻(xiàn),為了提高效率,進(jìn)行縮點(diǎn)
5.[HNOI2010]城市建設(shè)?
cdq分治,把一定不會(huì)在最小生成樹的邊提前刪掉,一定在的提前加上。其實(shí)還是縮點(diǎn)提高效率
最短路
常用dij和floyd(spfa)
考慮某些邊、點(diǎn)和最短路關(guān)系,往往需要統(tǒng)計(jì)每個(gè)點(diǎn)開始、結(jié)束的最短路信息
還有一些建超級(jí)匯的操作
最短路樹,最短路DAG,或者任意某條最短路都可以做文章
兩個(gè)源匯的確切路徑,考慮分層分步
例題1
你在一個(gè)國(guó)家旅游,國(guó)家可以看做有向圖
? 每一條邊都有過(guò)路費(fèi)
? 在每一個(gè)點(diǎn),你可以選擇花費(fèi) ?? 購(gòu)買魔法棒,當(dāng)你持有魔法棒時(shí),
你所經(jīng)過(guò)的所有邊都會(huì)永久免費(fèi)(第一次也不需要付錢),但是
最后你必須把魔法棒放回這個(gè)點(diǎn)
? 你可以無(wú)限購(gòu)買魔法棒
每個(gè)SCC至少購(gòu)買一個(gè)魔法棒
? 求能經(jīng)過(guò)盡量多的城市的前提下,你所花費(fèi)的最小代價(jià)
?
求SCC,topoDp
對(duì)于每個(gè)SCC,要知道從某個(gè)點(diǎn)開始,走若干個(gè)邊,然后買魔法棒的最小花費(fèi)
買魔法棒就停止了,可以當(dāng)做終止節(jié)點(diǎn)
多起點(diǎn)多終點(diǎn)?
每個(gè)終點(diǎn)向T連接pi的邊,然后從T跑最短路即可
?
?例題2
? 給出一張圖,每個(gè)點(diǎn)上有很多人,每條邊上也有很多重邊
? 設(shè)一個(gè)點(diǎn)的重要程度為
Pr表示概率
? 求每個(gè) v?
? ? ≤ 3000, ? ≤ 10000 Vp = §,
cnt(a,b)表示a到b的最短路徑條數(shù)
直接的式子是枚舉p再枚舉a,b,O(n^3)
考慮能不能“繼承點(diǎn)東西”降低復(fù)雜度
?
具體地,枚舉A,給所有的p貢獻(xiàn)可能的B
對(duì)于A,求出A的最短路徑DAG
對(duì)于一個(gè)p,p能到達(dá)的節(jié)點(diǎn)B,AB的最短路,p都是可行點(diǎn)
但是cnt(p,b)不能分離,看起來(lái)還是3次方的
發(fā)現(xiàn),p后面的DAG,恰好一定也是p的最短路徑DAG的一部分!
所以倒序topo,每個(gè)點(diǎn)T有一個(gè)權(quán)值T/cnt(A,T),后繼貢獻(xiàn)直接加起來(lái),cnt(p,b)自然就得到了
例題3:
? 給出一張 DAG,求出有多少點(diǎn)對(duì) ?, ?,使得任意從 ? 到 ? 的路徑
都恰好經(jīng)過(guò) ?, ? 中的任意一點(diǎn)
? ?, ? ≤ 100000
考慮兩個(gè)點(diǎn)a,b合法的充分必要條件:
1.a,b互不可達(dá)
2.cnt[s][a]*cnt[a][t]+cnt[s][b]*cnt[b][t]=cnt[s][t]
topo搞到拓?fù)湫蚝蚦nt,
把val[*]=cnt[s][*]*cnt[*][t]進(jìn)行離散化,開值域個(gè)bitset
倒序考慮拓?fù)湫?#xff0c;枚舉a
bitset處理可以到達(dá)的集合S
得到val[b]的值,S取反,和這個(gè)val[b]的bitset取交,交的個(gè)數(shù)就是貢獻(xiàn)
然后把val[a]的a位置設(shè)置為1
這樣就保證了a,b互不可達(dá)
例題4
給出一棵樹,邊權(quán)為正
隨機(jī)選出 ? 個(gè)關(guān)鍵點(diǎn),然后選擇一種移動(dòng)總距離最短的方案,從
其中某個(gè)點(diǎn)出發(fā),經(jīng)過(guò)每個(gè)關(guān)鍵點(diǎn)至少一次
求出移動(dòng)總距離最短的方案的期望
? ≤ 500
?
總距離最短:虛樹總邊長(zhǎng)*2-直徑
虛樹總邊長(zhǎng)*2:考慮邊的貢獻(xiàn),兩邊一共選擇k個(gè)
直徑:支持單點(diǎn)增量
不妨直接枚舉直徑(a,b),考慮對(duì)應(yīng)的點(diǎn)集個(gè)數(shù)
如果(a,b)加入p之后合法,也即max(dis(p,a),dis(p,b))<dis(a,b),那么p可以加入
這樣從所有能加入的p中選擇k-2個(gè)即可得到所有的方案數(shù)
但是一個(gè)虛樹多個(gè)直徑可能算重
方法:
每個(gè)邊(u,v)不妨u<v ,有額外權(quán)值:2^(-u),
這樣,一個(gè)虛樹直徑一定會(huì)在字典序最小的位置被求恰好一次,就完全分開了
例題5
給出一張有向圖,每條邊上有數(shù)字
對(duì)每一對(duì)點(diǎn)對(duì) ?, ? ,求從 ? 到 ? 的最短的回文路徑
? ≤ 500, ? ≤ 10^5
類似[HNOI2019]校園旅行
分成兩步走
f[a][b]表示a到b的最短路
每次讓a走一步
g[a][b][char]表示該b走了,a上一步走的字符是char的最短路
例題6
CF1163F Indecisive Taxi Fee
刪邊最短路
?
差分約束
如果能從題目中找到二元一次不等關(guān)系,即可差分約束
可以求一組最值解或者判斷有無(wú)解
是數(shù)形結(jié)合的思想
可能無(wú)解,所以時(shí)而還配合于二分
?
例題1
?51nod地鐵環(huán)線
可行的總長(zhǎng)是一段區(qū)間
考慮二分總環(huán)長(zhǎng)+SPFA判定
?先找右端點(diǎn),再找左端點(diǎn),
問(wèn)題是不合法的時(shí)候mid是大還是小
以最短路為例,x=mid
每個(gè)邊權(quán)值可以看做:kx+b
如果一個(gè)負(fù)環(huán)總和為Kx+B<=0
根據(jù)K的正負(fù)即可判定x過(guò)大還是過(guò)小
K=0顯然就無(wú)解了。
例題2
THUSC2018
圓環(huán)上有 ? 對(duì)藍(lán)點(diǎn),每一對(duì)藍(lán)點(diǎn)之間連了一條強(qiáng)度為 ?? 的線段
你需要在切割若干次,每次是用一條直線切割所有經(jīng)過(guò)的線段
如果一條線段被切割超過(guò) ?? 次,它就壞了
求至少要切割幾次
? ≤ 3000, ?, ?? ≤ 10000
每個(gè)線段兩側(cè)都至少>=k個(gè)切割點(diǎn)
對(duì)于所有的切割點(diǎn),i和i+tot/2進(jìn)行連邊
每個(gè)線段也會(huì)恰好被切割k次
同上題
甚至直接二分即可,不用Kx+b
拓?fù)渑判?/h2>
DAG是具有優(yōu)美性質(zhì)的圖
topo排序是分層圖的思想
topo序的先后含有一些到達(dá)關(guān)系
例題1
給出一張無(wú)向圖
求一個(gè)最大的子圖,使得每個(gè)點(diǎn)的度數(shù)都不小于 ?
? ≤ 10^6
不斷刪除度數(shù)小于d的點(diǎn)即可
例題2
兩個(gè)人在 DAG 上走,每個(gè)人都有自己的起點(diǎn)和終點(diǎn)
求兩個(gè)人不經(jīng)過(guò)一條邊的方案數(shù)(這里不經(jīng)過(guò)同一條邊指的是:路徑的邊沒(méi)有交集)
?, ? ≤ 1000
類似:[HNOI2019]校園旅行
還是分層變成回合制。使得多了一些可以共用的中間狀態(tài)
f[a][b]表示達(dá)到(a,b)的方案數(shù)
每次topo序小的先走
不經(jīng)過(guò)同一條邊?不能連續(xù)(i,i)->(j,j)
所以,中間變量g[a][b][0/1]表示一個(gè)走到a,一個(gè)走到b,上一次是否位置相同的方案數(shù)
O(nm)
例題3
[POI2014]RAJ-Rally
topo序好題
?
2-SAT
?[學(xué)習(xí)筆記](méi)2-SAT?問(wèn)題
命題蘊(yùn)含關(guān)系
各種優(yōu)化建圖
例題1
【UER #6】尋找罪犯
最難辦的是:最多說(shuō)一句謊
只給每個(gè)犯人開兩個(gè)點(diǎn)
每個(gè)犯人處理:他說(shuō)的,和說(shuō)他的
1.他是犯人
說(shuō)他不是犯人的都是犯人
說(shuō)他是犯人的人,只說(shuō)了這一句謊,所以這些人的說(shuō)的其他話都是真的。暴力連邊O(m^2)前綴后綴優(yōu)化即可
2.他不是犯人
說(shuō)他是犯人的都是犯人
他說(shuō)的話都是真的
?
Tarjan求方案即可
?
網(wǎng)絡(luò)流
過(guò)于博大精深
度數(shù)回路上下界:先走完限制,再調(diào)整
范圍較小的值域限制:切糕割
且關(guān)系的收益,或關(guān)系的花費(fèi):每個(gè)關(guān)系建新點(diǎn)
二元或關(guān)系的收益,且關(guān)系的花費(fèi):隔斷含義反轉(zhuǎn),二元關(guān)系最小割。(前提:涉及的點(diǎn)對(duì)構(gòu)成二分圖(這個(gè)“點(diǎn)”也可以是集合的且,詳見例題4))
一些依賴的帶點(diǎn)權(quán)最大化問(wèn)題:最大權(quán)閉合子圖
匹配問(wèn)題的DP:網(wǎng)絡(luò)流的匹配關(guān)系可以優(yōu)化DP,否則只能狀壓DP
如果有些東西一定會(huì)被計(jì)算:整體+權(quán)值可以把負(fù)權(quán)變成正權(quán)
各種網(wǎng)格、橫縱等:都具備一定二分圖性質(zhì),翻轉(zhuǎn)連邊,匹配
還有一些特殊題型和翻轉(zhuǎn)
例題1
給出一張無(wú)向圖,每條邊有一個(gè)次數(shù)限制
你需要找一條總長(zhǎng)度盡量短的可以不是簡(jiǎn)單路徑的回路,使得它
經(jīng)過(guò)每條邊至少那么多次
? ≤ 500
直接干掉下界
回路?每個(gè)點(diǎn)度數(shù)為2
兩點(diǎn)之間走一條路徑,只會(huì)使得起點(diǎn)終點(diǎn)度數(shù)奇偶改變
考慮奇度數(shù)節(jié)點(diǎn),兩個(gè)奇度數(shù)節(jié)點(diǎn)之間連接距離長(zhǎng)度的邊權(quán)
找一個(gè)最小權(quán)完美匹配即可
例題2
給出若干個(gè)定義在[0, ?] 的分段一次函數(shù)
請(qǐng)你把這些一次函數(shù)分成最少若干個(gè)組,使得每個(gè)組內(nèi)的一次函數(shù)兩
兩不相交
n<=250
不相交關(guān)系,形成DAG,求最小鏈覆蓋即可
例題3
文理分科
經(jīng)典且或關(guān)系問(wèn)題
例題4
有一個(gè)網(wǎng)格,每個(gè)格子你可以決定買不買
如果你買了一個(gè)格子,就要花費(fèi)其價(jià)格
如果你買了一個(gè)格子,或者買了和這個(gè)格子相鄰的所有格子,你
可以獲得這個(gè)格子的收益
最大化收益減去價(jià)格
n,? ≤ 100?
或有貢獻(xiàn),發(fā)現(xiàn)正是二分圖!
含義反轉(zhuǎn),貢獻(xiàn)關(guān)系單獨(dú)表示成點(diǎn)
本質(zhì)上還是兩個(gè)“點(diǎn)”的或關(guān)系,一個(gè)滿足有收益
這樣建圖:
黑白染色成為左右部點(diǎn)
ans+=所有收益
S到左部點(diǎn)cosi,右部點(diǎn)到T連cosi
由于共同收益和單點(diǎn)購(gòu)買的收益一樣,所以每個(gè)點(diǎn)像上圖一樣連好關(guān)系
這樣只要左邊都選,或者這個(gè)點(diǎn)選擇,那么這個(gè)收益就可以保留,否則收益必須割掉?
?
例題 5
[校內(nèi)練習(xí)]Trip
例題 6
彎彎國(guó)
? 給出一張網(wǎng)格圖,網(wǎng)格上有一些障礙
? 你需要給每個(gè)沒(méi)有障礙的網(wǎng)格放一個(gè)恰好連接網(wǎng)格的兩條邊的軌
道,同時(shí)使得這個(gè)軌道的兩端都和其他軌道的兩端相連
? 在一些格子里生活著一些彎的人,他們希望能讓自己所在的格子
里的鐵軌是彎的
? 求最多能滿足多少?gòu)澣说囊?br />? ?, ? ≤ 50
有點(diǎn)類似「清華集訓(xùn) 2017」無(wú)限之環(huán)
把所有彎的貢獻(xiàn)都加上
直有花費(fèi)
彎?一個(gè)向上下,一個(gè)向左右
直?都向上下,或者都向左右
拆邊費(fèi)用流!
上面兩個(gè)點(diǎn)連接上、下
下面兩個(gè)點(diǎn)連接左、右
這樣直一定有懲罰,彎不會(huì)有懲罰!
最小費(fèi)用最大流!
例題7
真實(shí)·網(wǎng)絡(luò)流優(yōu)化DP
? 在樹上選出兩個(gè)盡量大的不相交的同構(gòu)的連通塊
? ? ≤ 50
同構(gòu)?
枚舉邊
一半的根就是邊的端點(diǎn),枚舉另一半的樹根
有根樹,f(i,j)i為根,j為根的最大連通塊,對(duì)于du^2的兒子進(jìn)行帶權(quán)最大匹配
O(n^7)
發(fā)現(xiàn),可以記憶化!
因?yàn)榱硪话霕涓兓?#xff0c;其他的邊只是方向變化
f(e,j)一半邊e(帶方向),確定根的一半的j的子樹
可以記憶化
O(n^6)
非常不完全n^6,可過(guò)
例題8
在地圖上有一些敵人,每個(gè)敵人有一個(gè)消滅可獲得的價(jià)值
地圖上還有很多的發(fā)射器,每個(gè)發(fā)射器有最大的射程限制,同時(shí)
有一個(gè)朝向,保證沒(méi)有面對(duì)面的發(fā)射器
你可以對(duì)每個(gè)發(fā)射器指定一個(gè)射擊距離,這個(gè)發(fā)射器就會(huì)消滅發(fā)
射器朝向的這個(gè)方向的、距離恰好為這個(gè)射擊距離的敵人,但是
要求兩個(gè)發(fā)射器射擊時(shí)經(jīng)過(guò)的格子不能相交
求最多能消滅多少價(jià)值的敵人
?, ? ≤ 50
范圍很小,還有限制,考慮切糕割
但是這里的收益很難都算上然后扣去
但是由于每個(gè)發(fā)射器都要發(fā)射一定是最優(yōu)的
所以每個(gè)邊的流量是-v(i,j)+M,M是這一行的價(jià)值和
考慮用inf邊限制不能相交,只用考慮橫和縱
若x>=a,則y<b,若y>=b則x<a
如果連邊都是同一個(gè)方向,一個(gè)更小反而不合法
由于橫縱二分圖,把橫反過(guò)來(lái)連邊
即可
?
例題9
給出一棵樹,然后給樹上每一條邊染色,要求每個(gè)點(diǎn)的出邊顏色
互不相同
? 最小化每條邊所染顏色的編號(hào)和
? ? ≤ 150
設(shè)f[i][c]以i為根子樹,father到i的邊的顏色是c的最小編號(hào)和
顏色互不相同?匹配!
枚舉f[i][c]
S-每個(gè)兒子-分別連每個(gè)顏色c+f[soni][c]的邊-每個(gè)顏色連到T邊權(quán)為1
最小費(fèi)用最大流
O(n*m*dinic)
?
例題10
? 給出一張無(wú)向圖
? 請(qǐng)你往圖上加一些邊
? 加完邊后,設(shè)點(diǎn) ? 的距離是dp,那么總得分是 ∑c(p,dp)
? 最大化得分
? ≤ 50
其實(shí)最后只要滿足,對(duì)于原來(lái)有邊相連的點(diǎn)對(duì)(x,y)最后必然有|disx-disy|<=1
所以切糕割即可
一定有一種方案還原
例題11
[CQOI2014]危橋
另類網(wǎng)絡(luò)流
?
例題12
給出一張無(wú)向圖,每條邊有一個(gè)經(jīng)過(guò)時(shí)間
? 現(xiàn)在有 ? 個(gè)乘客,它們分別在第 ?i個(gè)點(diǎn),并且都想前往點(diǎn) 1
? 所有人都只想走一條最短路,并且同時(shí)從起點(diǎn)出發(fā)
? 如果兩個(gè)人同時(shí)同向經(jīng)過(guò)同一條邊,那么堵塞了,不合法
? 請(qǐng)你求出一個(gè)盡量大的乘客的子集,使得不會(huì)出現(xiàn)擁塞
找最短路徑圖
最短路不同,不會(huì)堵塞
對(duì)于最短路相同的所有人,分別跑一遍最大流
?
轉(zhuǎn)載于:https://www.cnblogs.com/Miracevin/p/10851212.html
總結(jié)
- 上一篇: 树的遍历和代码实现
- 下一篇: springboot配置Filter的两