HDU 1853 HDU 3488【有向环最小权值覆盖问题 】带权二分图匹配 KM算法
HDU 1853 & HDU 3488【有向環(huán)最小權(quán)值覆蓋問題 】最小費(fèi)用最大流
In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one-way roads connecting them. You are lucky enough to have a chance to have a tour in the kingdom. The route should be designed as: The route should contain one or more loops. (A loop is a route like: A->B->……->P->A.)?
Every city should be just in one route.?
A loop should have at least two cities. In one route, each city should be visited just once. (The only exception is that the first and the last city should be the same and this city is visited twice.)?
The total distance the N roads you have chosen should be minimized.?
Input
An integer T in the first line indicates the number of the test cases.?
In each test case, the first line contains two integers N and M, indicating the number of the cities and the one-way roads. Then M lines followed, each line has three integers U, V and W (0 < W <= 10000), indicating that there is a road from U to V, with the distance of W.?
It is guaranteed that at least one valid arrangement of the tour is existed.?
A blank line is followed after each test case.
Output
For each test case, output a line with exactly one integer, which is the minimum total distance.
Sample Input
1 6 9 1 2 5 2 3 5 3 1 10 3 4 12 4 1 8 4 6 11 5 4 7 5 6 9 6 5 4Sample Output
42題意:
給出n個(gè)點(diǎn)m條單向邊邊以及經(jīng)過每條邊的費(fèi)用,讓你求出走過一個(gè)哈密頓環(huán)(除起點(diǎn)外,每個(gè)點(diǎn)只能走一次)的最小費(fèi)用。
二分圖最大權(quán)匹配 KM算法
有向環(huán)最小權(quán)值覆蓋問題可以使用KM算法(帶權(quán)二分圖匹配算法)
我們把任意一個(gè)頂點(diǎn)i都分成兩個(gè),即i和i’. 如果原圖存在i->j的邊,那么二分圖有i->j’的邊.
?????? 下面我們要引出幾條結(jié)論:
? ? ? 1.?如果原圖能由多個(gè)不相交的有向環(huán)覆蓋,那么二分圖必然存在完備匹配.
(假設(shè)原圖的有向環(huán)為(1->2->3->1) and(6->5->4->6),那么二分圖的完備匹配就是1->2’ 2->3’ 3->1’6->5’ 5->4’ 4->6’)
???????2.如果二分圖存在完備匹配,那么原圖必定能由幾個(gè)不相交的有向環(huán)覆蓋.
(假設(shè)二分圖的完備匹配是1->2’ 2->3’ 3->1’ 6->5’ 5->4’ 4->6’那么原圖的有向環(huán)為(1->2->3->1) and (6->5->4->6))
???????3.如果原圖存在權(quán)值最大的有向環(huán)覆蓋,那么二分圖的最優(yōu)匹配一定就是這個(gè)值.
(因?yàn)樵撚邢颦h(huán)覆蓋對(duì)應(yīng)了一個(gè)二分圖的完備匹配,而該完備匹配的權(quán)值就等于該有向環(huán)覆蓋的權(quán)值,所以最優(yōu)匹配不可能丟失該最大權(quán)值的匹配)
有解:
?????? 現(xiàn)在原題要求的是最小長(zhǎng)度匹配,我們把所有已知邊的權(quán)值都取負(fù)數(shù),且那些不存在的邊我們?nèi)?INF(負(fù)無窮). 如果完備匹配存在,那么我們求出的最優(yōu)匹配權(quán)值的絕對(duì)值 肯定<INF. 且該絕對(duì)值就是最小權(quán)值匹配.
無解:
?????? 如果完備匹配不存在,那么最優(yōu)匹配權(quán)值的絕對(duì)值 肯定>INF,?或者這么說,如果最終求得的匹配中,有任何一個(gè)匹配邊用了權(quán)值為負(fù)無窮的邊,那么最優(yōu)匹配不存在(即完備匹配不存在)
?????? 注意:此題輸入可能存在重邊.
#include<cstdio> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #include<queue> using namespace std; #define INF 0x3f3f3f3f const int maxn=1e4+10; int n,m; int w[maxn][maxn]; int lx[maxn],ly[maxn]; int link[maxn]; int slack[maxn]; int visx[maxn],visy[maxn]; bool dfs(int x) {visx[x]=1;for(int y=1;y<=n;y++){if(visy[y]) continue;int t=lx[x]+ly[y]-w[x][y];if(t==0){visy[y]=1;if(link[y]==0||dfs(link[y])){link[y]=x;return 1;}}else if(slack[y]>t) slack[y]=t;}return 0; } int km() {memset(lx,0,sizeof lx);memset(ly,0,sizeof ly);memset(link,0,sizeof link);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(lx[i]<w[i][j])lx[i]=w[i][j];for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)slack[j]=INF;while(1){memset(visx,0,sizeof visx);memset(visy,0,sizeof visy);if(dfs(i)) break;int d=INF;for(int k=1;k<=n;k++)if(!visy[k]&&d>slack[k])d=slack[k];for(int k=1;k<=n;k++){if(visx[k]) lx[k]-=d;if(visy[k]) ly[k]+=d;}}}int ans=0;for(int i=1;i<=n;i++){//if(w[link[i]][i]==-INF) return -1;ans+=w[link[i]][i];}return -ans; } int main() {int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);int u,v,cost;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)w[i][j]=-INF;for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&cost);cost=-cost;if(w[u][v]!=-INF)//去重邊,取權(quán)值最小的邊建圖cost=max(cost,w[u][v]);w[u][v]=cost;//w[v][u]=cost;}printf("%d\n",km());} }總結(jié)
以上是生活随笔為你收集整理的HDU 1853 HDU 3488【有向环最小权值覆盖问题 】带权二分图匹配 KM算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU 1853 HDU 3488【有
- 下一篇: HDU1599 find the min