洛谷P2764 最小路徑覆蓋

2022-05-16 06:56:21 字數 1272 閱讀 8181

給定有向圖 g=(v,e) 。設 p 是 g 的乙個簡單路(頂點不相交)的集合。如果 v 中每個定點恰好在p的一條路上,則稱 p 是 g 的乙個路徑覆蓋。p中路徑可以從 v 的任何乙個定點開始,長度也是任意的,特別地,可以為 0 。g 的最小路徑覆蓋是 g 所含路徑條數最少的路徑覆蓋。設計乙個有效演算法求乙個 dag (有向無環圖) g 的最小路徑覆蓋。

第一行有 2 個正整數 n 和 m 。 n 是給定\(\text\)(有向無環圖) g 的頂點數, m 是 g 的邊數。接下來的 m 行,每行有兩個正整數 i 和 j 表示一條有向邊 (i,j)。

從第1 行開始,每行輸出一條路徑。檔案的最後一行是最少路徑數。

洛谷由已知條件,每個點的入度和出處均為0。為滿足這一限制,不妨將每個點\(x\)拆成兩個點\(x1,x2\),源點向其中乙個連邊,另乙個向匯點連邊。對於原圖上存在的邊\((u,v)\),我們從\(u1\)向\(v2\)連邊。每條邊的容量均為1,代表度數限制。這張圖的最大流顯然是\(n\),那麼我們只需要跑一邊最大流,然後對於殘量網路上原圖對應的邊,如果滿流說明路徑覆蓋集中包含這條邊,輸出即可。

#include #include #include #include #define n 152

#define m 6002

using namespace std;

const int inf=1<<30;

int head[2*n],ver[m*2],nxt[m*2],cap[m*2],l;

int head1[n],ver1[m],nxt1[m],l1;

int n,m,i,j,s,t,dis[2*n],d[n],ans;

int read()

return w;

}void insert(int x,int y,int z)

bool bfs()

} }return (dis[t]>0);

}int dfs(int x,int flow)

if(flow==0) break;

} if(flow) dis[x]=-1;

return ans;

}void dinic()

void insert1(int x,int y)

void print(int x)

int main()

dinic();

for(i=1;i<=n;i++)

} for(i=1;i<=n;i++)

printf("%d\n",ans);

return 0;

}

洛谷P2764 最小路徑覆蓋問題

剛一看到這道題十分的懵,完全不知道從何下手 然後看了看題解後發現,這道題的關鍵就是計算可以合併多少次路徑,然後最小的路徑覆蓋數就是總點數 合併次數。舉個例子 僅僅是讓你理解上面一句話,而不一定是真正的 執行流程 初始 合併1次 合併2次 合併3次 所以最後最小路徑覆蓋數即為 5 3 2 注意 1 4...

P2764 最小路徑覆蓋

我們首先將原圖用n條路徑覆蓋,每條邊只經過乙個節點 本身 可以知道每合併兩條路徑,路徑覆蓋數就會減少1。現在盡量合併更多的路徑 即將兩個路徑通過一條邊首尾相連 所以拆點做二分圖最大匹配即可。includeusing namespace std const int maxn 510 const int...

P2764 最小路徑覆蓋問題

我做24題的第六題,輸出路徑還是有點糊塗 給定有向圖g v,e 設p是圖g上若干點不相交的簡單路徑的集合,若每個點v屬於v都存在於唯一一條p中的路徑上,則p是g的一條路徑覆蓋。路徑數量最少的路徑覆蓋稱為最小路徑覆蓋。用minpc g 表示圖g的最小路徑覆蓋數.有向無環圖的最小路徑覆蓋問題可轉化為二分...