Hopcroft_Karp算法
在匈牙利算法中,我们每次寻找一条增广路来增加匹配集合M.可以证明,每次找增广路的复杂度是O(E),一共需要增广O(V)次,因此总时间复杂度为O(VE).为了降低时间复杂度,在Hopcroft Karp算法中,我们在增加匹配集合M时,每次寻找多条增广路.可以证明,这样迭代次数最多为2*V^0.5,所以,时间复杂度就降到了O(V^0.5*E).
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <iterator>
using namespace std;
struct NodeGuest
{
double x, y, speed;
}ng[3010];
struct NodeNmbre
{
double x, y;
}nn[3010];
int T, cntGuest, cntUmbre, match;
int disx[3010], disy[3010], matx[3010], maty[3010], que[3010];
double t;
vector<int> mp[3010];
double getTime(int a, int b)
{
double dis = sqrt( (ng[a].x - nn[b].x) * (ng[a].x - nn[b].x) + (ng[a].y - nn[b].y) * (ng[a].y - nn[b].y));
return dis/ng[a].speed;
}
bool bfs()
{
int i, j, fore = 0, rear = 0;
bool flag = false;
vector<int>::iterator ite;
for(i=0; i<cntGuest; ++i){ //找出中还没有匹配的点
if(matx[i] == -1) que[rear++] = i;
disx[i] = 0;
}
for(i=0; i<cntUmbre; ++i) disy[i] = 0;
while(fore<rear){//从这些没有匹配的点里,找路径
int x = que[fore++];
for(ite=mp[x].begin(); ite!=mp[x].end(); ++ite){
if(disy[*ite] == 0){
disy[*ite] = disx[x] + 1;
if(maty[*ite] == -1) flag = true; //找到一条路径,则返回值是正的
else { //找不到路径,则把前向点如队列
disx[maty[*ite]] = disy[*ite] + 1;
que[rear++] = maty[*ite];
}
}
}
}
return flag;
}
bool dfs(int x)
{
vector<int>::iterator ite;
for(ite=mp[x].begin(); ite!=mp[x].end(); ++ite){
if(disy[*ite] == disx[x] + 1){
disy[*ite] = 0;
if(maty[*ite] == -1 || dfs(maty[*ite])){
matx[x] = *ite;
maty[*ite] = x;
return 1;
}
}
}
return false;
}
int Hopcroft_Karp()
{
int i;
match = 0;
memset(matx, -1, sizeof(matx));
memset(maty, -1, sizeof(maty));
while(bfs()){
for(i=0; i<cntGuest; ++i){
if(matx[i] == -1 && dfs(i)) ++match;
}
}
return match;
}
int main()
{
// freopen("c:/aaa.txt", "r", stdin);
int ca = 1;
scanf("%d", &T);
while(T--){
scanf("%lf %d", &t, &cntGuest);
int i, j;
for(i=0; i<cntGuest; ++i) scanf("%lf %lf %lf", &ng[i].x, &ng[i].y, &ng[i].speed);
scanf("%d", &cntUmbre);
for(i=0; i<cntUmbre; ++i) scanf("%lf %lf", &nn[i].x, &nn[i].y);
for(i=0; i<cntGuest; ++i) mp[i].clear();
for(i=0; i<cntGuest; ++i){
for(j=0; j<cntUmbre; ++j){
double tt = getTime(i, j);
if(tt <= t) mp[i].push_back(j);
}
}
printf("Scenario #%d:\n%d\n\n", ca++, Hopcroft_Karp());
}
return 0;
}
浙公网安备 33010602011771号