ハンガリーのアルゴリズムの改善したキューの最適化は極めて広いパスセットを探す--Hopcroft-Karpアルゴリズム【記録】
2539 ワード
アルゴリズムの解:ハンガリーのアルゴリズムと解決した問題は、時間の複雑さを最適化したにすぎない.
アルゴリズム解析:sqrt(n)回を広げ,毎回辺数m,時間複雑度−O(sqrt(n)*mを遍歴する必要がある.
アルゴリズムの実装:
1,BFSは交差しない複数の拡張パスを探し,極大拡張パスセットを見つける.この過程で配列dx[],dy[]を設定してXセット,Yセットの階層図を作成することは,メンテナンス距離ラベルとして理解できる.
(不適切かもしれませんが、この点は最大ストリームDinicアルゴリズムのBFSと拡張路を探していますが、ここでは複数を探しています).
2,それから原版ハンガリーアルゴリズムのマッチング過程であり,階層図の判定が多かったにすぎない.
3,ずっとBFSは極大な拡幅のパスのセットを探して、もし拡幅の道が存在しないならば、飛び出して、アルゴリズムは終わります.
最大BFS探索sqrt(n)回で最大整合が得られることを証明できる.
コード:
アルゴリズム解析:sqrt(n)回を広げ,毎回辺数m,時間複雑度−O(sqrt(n)*mを遍歴する必要がある.
アルゴリズムの実装:
1,BFSは交差しない複数の拡張パスを探し,極大拡張パスセットを見つける.この過程で配列dx[],dy[]を設定してXセット,Yセットの階層図を作成することは,メンテナンス距離ラベルとして理解できる.
(不適切かもしれませんが、この点は最大ストリームDinicアルゴリズムのBFSと拡張路を探していますが、ここでは複数を探しています).
2,それから原版ハンガリーアルゴリズムのマッチング過程であり,階層図の判定が多かったにすぎない.
3,ずっとBFSは極大な拡幅のパスのセットを探して、もし拡幅の道が存在しないならば、飛び出して、アルゴリズムは終わります.
最大BFS探索sqrt(n)回で最大整合が得られることを証明できる.
コード:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define MAXN 5000+10
using namespace std;
int mx[MAXN], my[MAXN];// X Y
int dx[MAXN], dy[MAXN];//
bool used[MAXN];//
vector<int> G[MAXN];//
int n, m;//
int numx, numy;// X Y
int DFS(int u)//
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(!used[v] && dy[v] == dx[u] + 1)
{
used[v] = true;
if(my[v] == -1 || DFS(my[v]))
{
my[v] = u;
mx[u] = v;
return 1;
}
}
}
return 0;
}
void HK_match()
{
memset(mx, -1, sizeof(mx));
memset(my, -1, sizeof(my));
int ans = 0;
while(1)
{
bool flag = false;//
memset(dx, 0, sizeof(dx));
memset(dy, 0, sizeof(dy));
queue<int> Q;
for(int i = 1; i <= numx; i++)
if(mx[i] == -1) Q.push(i);
while(!Q.empty())//
{
int u = Q.front(); Q.pop();
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(!dy[v])
{
dy[v] = dx[u] + 1;// Dinic
if(my[v] == -1)//
flag = true;
else
{
dx[my[v]] = dx[u] + 1;
Q.push(my[v]);
}
}
}
}
if(!flag)//
break;
memset(used, false, sizeof(used));
for(int i = 1; i <= numx; i++)
if(mx[i] == -1)//
ans += DFS(i);
}
printf("%d
", ans);// X、Y , numx = numy = n, 2。
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
getMap();// G
HK_match();//HK
}
return 0;
}