网络流及建模专题(下)
前言
不斷更新中…
專題的(下)篇將介紹網絡流的一些奇奇怪怪的應用和費用流有關的一些套路。
本專題暫時包含三道題:
洛谷P1251 餐巾計劃問題: 費用流的基本應用
Trade Gym - 100212I: 使用網絡流對圖論中的邊進行調整
codeforces 818G - Four Melodies: 費用流壓縮建圖
洛谷P1251餐巾計劃問題
題意
見題目鏈接
題解
這道題我們把選取一張餐巾紙當作是一個單位的流量,那么顯然來源部不同的餐巾紙,他們的費用是不相同的,這就引出了費用流(最小費用最大流)的模型。
每一天可以在早上接受r[i]r[i]數量的餐巾紙,同時也可以將r[i]r[i]數量的餐巾紙送去清洗,所以我們需要將每一天拆成兩個點,分別表示需要餐巾紙的點和送走餐巾紙的點。
需要餐巾紙的點與匯點TT連邊,容量為r[i]r[i],費用為00。還要和源點SS連邊,容量為r[i]r[i],費用為pp,這代表購買新的餐巾紙的方式。
送走餐巾紙的點需要和兩個點進行連邊:
- 送去慢洗,則需要和nn天以后的需求點連邊,容量為infinf,費用為慢洗一條的費用。
- 送去快洗,則需要和mm天以后的需求點連邊,容量為infinf,費用為快洗一條的費用。
注意,由于一條餐巾紙洗完了可以存放任意時間,所以我們需要在相鄰需求點之間連立一條費用為00,容量為infinf的邊,代表的含義就是餐巾紙在存放。
如圖所示:
優化:由于BB累點之間有邊相連,表示餐巾紙可以存放到下一天,那么,我們可以把S?>BS?>B的邊省略掉,只保留S?>1BS?>1B這條邊,表示所有新購買的餐巾紙都在第一天買好,然后存放到需要的那一天再使用。
優化圖如下:
這樣建圖完成以后,跑一個最小費用最大流就可以了。
注意:請檢查你的板子速度是否可行,我的板子速度就太慢了,zkw費用流模板了解一下。參考代碼 略
Trade Gym - 100212I
題意
給出A、B兩個點集,A、B之間有邊相連,而A和B的內部均無邊相連。
題目要求求出最多刪除A、B之間的多少邊,才能使得A中點的度數至少都為2,B中點的度數也至少都為2。題解
先求出每個點的度數,從每個點v出發,最多能刪除deg[v]?2deg[v]?2條邊(注意這里是理想情況下,不一定能刪除這么多)。
那么我們就可以建立一個超級源點SS和超級匯點TT,從SS往AA點集連邊,邊的容量為deg[v]?2deg[v]?2,從BB點集往TT點連邊,邊的容量為deg[u]?2deg[u]?2
AA和BB之間的邊流量全為11。
從SS點流到TT的每一個為11的流量,都相當于在原圖里面刪除了這條邊。
跑一邊最大流,就可以得到最多能刪除多少邊了。在殘余網絡中做一些小操作就可以把剩余的邊輸出出來。
網絡圖如下:
總結
網絡流可以用于對圖論中的邊進行調整,當圖論中的一條邊存在流量流過的時候,代表該邊被“調整”了,調整可以具有很多含義,比如本題中的“刪除”也算“調整”。
參考代碼 略
Four Melodies
題意
題目鏈接
給出nn個數,輸出選四個不相交的melody的所有情況中,4個melody長度總和的最大值。
要形成Melody,要求相鄰的數字要么相差11,要么相差77的倍數。
題解
一種很直觀的建圖方法就是把每個數字拆成2個點inin和outout,然后源點也拆成2個點ss和s′s′,并把s′s′作為費用流的源點。
從s′?>ss′?>s建立一條容量為44費用為00的邊。然后從ss點向每個inin建立一條容量為11,費用為00的邊。
再從inin向outout建立一條容量為11,費用為?1?1的邊。從outout向匯點tt建立一條容量為11,費用為00的邊。
然后對于任意兩個node.i,jnode.i,j如果ii到jj符合相鄰的22個條件,那么就從i的outout點向j的inin點連接一條容量為11費用為00的邊,表示他們可以串起來。
這樣的話,建圖的復雜度為O(n2)O(n2),邊的個數也為O(n2)O(n2),復雜度太高了,因此需要壓縮建圖。
奇技淫巧:當你找不到任何優化的點的時候,可以考慮搞一個出錯率極小的做法,有一個想法就是每個點僅向后面50個點連邊。
怎么壓縮建圖呢?
把每個點都擴充成3個點in,mid,outin,mid,out,其中inin往midmid 連邊容量為11,費用為?1?1,midmid往outout連邊,容量為11,費用為00。
從inin往outout連邊容量為infinf,費用為00,表示途徑這個點。
關鍵的一步來了:
從i這個點往后找第一個使得val[i]=val[j]+1val[i]=val[j]+1的點jj,從i.outi.out向j.inj.in連接一條容量為11,費用為00的邊。
從ii這個點往后找第一個使得val[i]=val[j]?1val[i]=val[j]?1的點jj,從i.outi.out向j.inj.in連接一條容量為11,費用為00的邊。
從i這個點往后找第一個使得(val[i]?val[j])%7==0(val[i]?val[j])%7==0的點jj,從i.outi.out向j.inj.in連接一條容量為11,費用為00的邊。
這樣的話,圖就算壓縮完成了(不需要兩兩比較建圖)。
圖舉例:
總結
以上是生活随笔為你收集整理的网络流及建模专题(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最佳入手时机?摩尔线程 MTT S80
- 下一篇: Problem H Rock Paper