開始了我的網路流 \(24\) 題之旅,寫在一起到時候方便一起複習哦。
其實這並不是真的二十四題,有一些過於水的我就不寫上來了。然後有的**太水了就不寫了。
感覺這些題目還是比較基礎的,方法卻值得借鑑!
剩餘題目: 航空路線問題、火星探險問題以下
題目描述
點此看題
解法
你發現時間是最大的障礙,因為對於不同的時間飛船的行駛是不同的。
但是你發現資料小得一批,如果我們每次都運乙個人的話,並且花最多的時間等飛船,可以計算出時間的上界是 \(n^2m\) ,這給了我們一些暴力思想的可能,不妨在每個時間都建出這張圖,構圖方法如下:
一開始我們可以用並查集判斷有無解,然後我們邊列舉答案邊構圖,邊跑最大流。如果最大流大於等於 \(k\) 就表示可以把 \(k\) 個人運到終點了,得到了答案。好像不怎麼難啊
#include #include using namespace std;
const int n = 55;
const int m = 200005;
const int inf = 0x3f3f3f3f;
int read()
int n,m,k,mx,tot,ans,s,t,f[m],cur[m],dis[m],h[n],r[n],fa[n],a[n][n];
struct edge
e[2*m];
int find(int x)
void merge(int u,int v)
void add(int u,int v,int c)
,f[u]=tot;
e[++tot]=edge,f[v]=tot;
}bool bfs()
} }return 0;
}int dfs(int u,int ept)
} return flow;
}int main()
for(int i=1;i<=n+1;i++)
add((ans-1)*(n+1)+i,ans*(n+1)+i,inf);
}}
題目描述點此看題
最大權閉合子圖問題,有 \(n\) 個正權點,\(m\) 個負權點,正權點和負權點之間有邊,表示選了這個正權點之後必須選相連的負權點,如果滿足這個條件就稱為閉合,求最大權值。
\(n,m\leq50\)
解法
這是乙個經典模型,在題目描述裡面已經介紹了一些概念,我們這樣建圖:
然後求出最小割,答案是正權點權值 \(-\) 最小割。
現在來證明為什麼,要明確乙個至關重要的結論:乙個點要麼和 \(s\) 聯通,要麼和 \(t\) 聯通。首先中間些容量為 \(inf\) 是斷不掉的,不用管它們,考慮如果乙個點既不能連向 \(s\) 又不能連向 \(t\) ,如果是正權點,那麼可以不斷掉和 \(s\) 的連邊,如果是負權點可以不斷掉和 \(t\) 的連邊,由於是最小割,但是在同樣在不連通的情況下卻多斷了點,矛盾,反證成立。
然後考慮正權點和 \(s\) 不斷邊的意義是選取這個正權點,負權點不斷邊的意義是不選這個負權點,由於要保證不連通性那麼選了正權點他相連的負權點就不會選,所以滿足了閉合的條件。然後考慮是否滿足最大化答案,答案可以表示為正權點權和 \(-\) 沒選取的正權點 \(-\) 選取了的負權點。發現我們求的就是 \(\min\\) ,所以也滿足最大哦。
這個模型挺有意思的,但是如果不知道這個模型做題就有點麻煩,其實可以最大流和最小割都試一試,看哪個滿足題目條件,也可以把點的順序交換一下(一開始我源點連器材就死活想不出來)
題目描述
點此看題
解法
這道題看到沒什麼思路,但是我們可以用調整法。也就是一開始的路徑都是只經過單點的,我們把它調整得更優。很多題都是這樣的,沒什麼思路的時候一定要試一試調整法,它的解決範圍是很廣的。
考慮用網路流來實現這個調整的過程,我們把每條路徑拆成 \(y\) 前端和 \(x\) 後端。如果 \((i,j)\) 有一條有向邊那麼就可以把 \(i\) 的 \(x\) 連向 \(j\) 的 \(y\) ,如果這一條邊上有流量那麼就表示我們把 \(i\) 和 \(j\) 接在一起了,構圖方法如下:
最後會是 \(y-x-y-x-y-x\) 之類的路徑覆蓋,如果我們跑最大流的話就可以得到最小路徑覆蓋。輸出方案數的話就看哪條邊是使用過的,如果你弄懂了上面那些肯定就會輸出方案啦!
題目描述
點此看題
解法
做到這道題我才發現乙個很重要的東西:有些題是不能直接根據題目意義網路流的,要先把他用圖論表示出來,然後這個圖論問題的解決可能使用到網路流,這位大佬的思路實在是太強了!
首先柱子是辣雞,基本上沒卵用,你會發現關鍵還是在數,我們把具有完全平方數關係的兩個點 \((x,y)\) 連一條有向邊,就可以得到一張圖,要注意的是 \(x,這種圖稱為隱式圖,比如樣例的圖長這樣:
那麼問題變成了我們選出 $n $ 條路徑使得能覆蓋 \([1,ans]\) 的所有點,貌似不是很好做。因為 \(n\) 很小,所以到了後面選數就很容易沒位置填,所以 \(ans\) 不會很大。我們可以列舉 \(ans\) ,那麼問題就變成了 \([1,ans]\) 的點都能被覆蓋的路徑數 \(\leq n\) 的最大的 \(ans\) ,這就轉化成了最小路徑覆蓋問題
題目描述
點此看題
解法
我覺得上一道題那位大佬介紹的方法真是太好用啦!
首先跑 \(dp\) ,設 \(dp[i]\) 為以 \(i\) 為結尾的最長不下降子串行長度。然後我們構建出圖論模型,對於 \(i,如果 \(dp[j]+1=dp[i]\) 那麼我們就把連一條 \((i,j)\) 的邊,問題轉化成了:取出若干條不相交的長度為 \(\max\) 的路徑,要求最大化路徑數量。
可以用網路流來完成這個最大化的過程,我們把每個點分成 \(x\) 端和 \(y\) 端,這樣建圖:
然後第二問就解決了,第三問就修改網路中的這些邊容量無限: \((s,x_1),(x_1,y_1),(x_n,y_n),(y_n,t)\) ,就表示這兩個點可以無限使用,寫著很簡單,**就不給了。
題目描述
點此看題
解法
套路題,遇到矩陣之類的題都要注意一下了,我們可以按奇偶性來劃分原矩陣,然後把這個問題轉化為二分圖。也就是 \(i+j\) 為奇數的就歸到 \(x\) 部,\(i+j\) 偶數就歸到 \(y\) 部,本題 \(x\) 部連 \(y\) 部表示選了 \(x\) 部的這個點就不能選 \(y\) 部的那個點。這個題感覺和最大權閉合子圖問題有點像,我們可以這樣構圖:
然後跑最小割,還是因為乙個點必須和 \(x\) 聯通或者 \(y\) 聯通,斷掉某一條邊就表示不選這條邊的對應點。那麼要求斷掉的邊權值最小,那麼就跑最小割。
題目描述
點此看題
解法
特別經典的模型,而且特別有用,我給它起了個名字:補流模型
為什麼我們要這樣取名呢?當我們把餐巾當成容量,然後跑費用流。如果我們流到匯點之後,這個流量就消失了,但是我們還需要這個流量,因為餐巾是可以被洗乾淨的,所以我們選擇從源點補充這些被匯點拿走的流量,就達到了重複利用餐巾的效果,具體這樣建圖:
題目描述
點此看題
解法
和[noi2008]志願者招募
是乙個模型,我們可以把區間看成 \([l_i,r_i)\) ,這樣我們就只用考慮整數點了,本題的要求是對於每個點不能超過 \(k\) 次覆蓋。
我們講所有整數點排成一排,源點連第乙個整數點,匯點連第二個整數點,相鄰兩個連邊,容量為 \(k\) ,費用為 \(0\) ,這是一開始的狀態。
然後考慮加入我們的區間,我們講 \(l_i\) 和 \(r_i\) 連一條容量為 \(1\) ,費用為 \(r_i-l_i\) 的邊,表示使用了這個區間就會給 \([l_i,r_i)\) 都減少 \(1\) 的流量。由於流量是 \(k\) 且不可能減到負數,所以限制成功地在圖上被表示了出來。然後發現本題只有端點的整數點有用,所以一開始需要離散化。
題目描述
點此看題
解法
和上面的那一道題一樣,就是長度的計算方式變了一下?
不不不,我們上一道題保證了 \(l,但是這道題會出現 \(l=r\) 的情況。對於線段 \((l,l)\) 和 \((l,r)\) 理應在 \(l\) 點不相交,但是我們把管轄的區間設為 \([l,l)\) 和 \([l,r)\) 就會判成相交了,所以並不完全等價。
遇到這種衝突我們考慮擴域,把每個線段變成 \((2l,2r)\) ,對於 \(l=r\) ,把他管轄的區間設為 \([2l,2l+1)\),對於其他線段,要避免判成相交,我們就把它管轄的區間設為 \([2l+1,2r)\) ,就很巧妙地解決了衝突。
網路流二十四題之分配問題
沒想到codevs上的資料和我本地的資料是一樣的 這下不用寫多餘的 了 這道題和上一道題一樣水,按照提議寫成二分圖就行。1.源點向每個人連一條邊,容量1,費用0,每個任務向匯點連一條邊,容量1,費用0 2.每個人向每個任務連一條邊,容量1,費用為cij 跑兩次費用流就行 include includ...
網路流二十四題之航空路線問題
這道題的建模很有意思 1.首先每個點,除了起點,都向拆點後的點練一天容量1,費用 1的邊,代表只能走一次,負費用是為了求最大的費用,也就是最多的經過點。對於起點,容量變成2,費用不變。2.其次對於一天航線,終點在拆點後的點集向起點連一條邊,容量無限,費用為0,代表兩個城市可以達到。之後一次費用流,如...
網路流二十四題之星際轉移問題
這道題的建模是按照天數建模的分層模型,然後列舉需要多少天,需要對標號進行合理的設計。1.每一天的地球,月球分別向源點,匯點連一條邊,容量inf 2.對於n個空間站,向他的下一天連一條邊,容量無限 3.如果有一天飛船在前一天在i,這一天在j那麼將這兩個點連線在一起。然後每天判斷是否滿流 include...