題目大意:
對於給定的有向無環圖,找出其中的最小路徑覆蓋,並列印出第一條路徑。
題目測試資料與資料範圍:
11 12
1 21 3
1 42 5
3 64 7
5 86 9
7 10
8 11
9 11
10 11
1 4 7 10 11
2 5 8
3 6 9
頂點數與邊數的範圍不定。
題目分折:
有向無環圖最小路徑覆蓋,可以轉化成二分圖最大匹配問題,從而用最大流解決。構造二分圖,把原圖每個頂點i拆分成二分圖x,y集合中的兩個頂點xi和yi。對於原圖中存在的每條邊(i,j),在二分圖中連線邊(xi,yj)。然後把二分圖最大匹配模型轉化為網路流模型,求網路最大流。最小路徑覆蓋的條數,就是原圖頂點數,減去二分圖最大匹配數。沿著匹配邊查詢,就是乙個路徑上的點,輸出所有路徑即可。對於乙個路徑覆蓋,有如下性質:
1、每個頂點屬於且只屬於乙個路徑。
2、路徑上除終點外,從每個頂點出發只有一條邊指向路徑上的另一頂點。
小樂一下:
所以我們可以把每個頂點理解成兩個頂點,乙個是出發,乙個是目標,建立二分圖模型。該二分圖的任何乙個匹配方案,都對應了乙個路徑覆蓋方案。如果匹配數為0,那麼顯然路徑數=頂點數。每增加一條匹配邊,那麼路徑覆蓋數就減少乙個,所以路徑數=頂點數 - 匹配數。要想使路徑數最少,則應最大化匹配數,所以要求二分圖的最大匹配。注意,此建模方法求最小路徑覆蓋僅適用於有向無環圖,
我的**,無論你怎麼說,我總是覺得劉汝佳的**格式很優秀,當然,更好更簡潔的由你來實現,不能直接複製。
#include#include#include#include#include#includeusing namespace std;
const int inf = 0x3fffffff;
const int maxn = 1005;
struct edge;
struct dinic}}
return vis[t];
}int dfs(int x,int a)
}return flow;
}int maxflow(int s,int t)
return flow;
}void topath(int n)
else printf(" %d",tmp);
for(int i = 0;i0)}}
printf("\n");}}
};int main()
printf("%d\n",n-graph.maxflow(0,2*n+1));
graph.topath(n);
}return 0;
}
偉大的夢想成就偉大的人,從細節做好,從點點滴滴做好,從認真做好。
網路流 最小路徑覆蓋問題
每條邊的容量均為1。求網路g1的 x0,y0 最大流。對於給定的給定有向無環圖g,程式設計找出g的乙個最小路徑覆蓋。輸入 由檔案input.txt提供輸入資料。檔案第1 行有2個正整數n和m。n是給定有向無環圖 g 的頂點數,m是g 的邊數。接下來的m行,每行有2 個正整數i和j,表示一條有向邊 i...
網路流最小路徑覆蓋
思路 每個點x拆成兩個點x和x 分別表示x作為前驅和作為後繼。若原圖中x和y有邊,向x和y 加一條有向邊。如此構成二分圖,記此二分圖中作為前驅的節點集合為a,作為後繼的節點集合為b。跑最大匹配,沒有匹配的點的個數 n 最大匹配數 就是需要的最少的路徑條數。正確性 二分匹配可以保證每個點頂多只有乙個前...
網路流24題 最小路徑覆蓋 (最小路徑覆蓋)
題目 給定有向圖g v,e 設p是g的乙個簡單路 頂點不相交 的集合。如果v中每個頂點恰好在p的一條路上,則稱p是g的乙個路徑覆蓋。p中路徑可以從v的任何乙個頂點開始,長度也是任意的,特別地,可以為0。g的最小路徑覆蓋是g的所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個有向無環圖g的最小路徑覆...