您的位置:首页 > 运维架构

hdu2389+二分匹配(Hopcroft-Karp算法)

2016-05-17 11:08 453 查看
题意很简单,显然是对客人与伞做匹配,求最大匹配数。

一开始用了匈牙利,果断TLE。。。

好吧,原来二分匹配还有这个奇葩算法。。然而敲完还是不明白这个算法啥意思。。。

附两个算法的时间复杂度:

匈牙利:O(VE)

H-K :O(V^0.5 E)

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
int nx,ny,mx[3300],my[3300],dx[3300],dy[3300],vis[3300];
vector<int> v[3300];
struct node1
{
int x,y,sp;
}per[3300];
struct node2
{
int x,y;
}umb[3300];
bool dfs(int u)
{
int v2,i;
for(i=0;i<v[u].size();i++)
{
v2=v[u][i];
if(!vis[v2]&&dy[v2]==dx[u]+1)
{
vis[v2]=1;
if(my[v2]==-1||dfs(my[v2]))
{
my[v2]=u;
mx[u]=v2;
return true;
}
}
}
return false;
}
int hkmatch()
{
int ret=0;
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));
while(true)
{
int i;
bool flag=false;
queue<int> q;
memset(dx,0,sizeof(dx));
memset(dy,0,sizeof(dy));
for(i=1;i<=nx;i++)
{
if(mx[i]==-1)
{
q.push(i);
}
}
while(!q.empty())
{
int z=q.front();
q.pop();
for(i=0;i<v[z].size();i++)
{
int vv=v[z][i];
if(!dy[vv])
{
dy[vv]=dx[z]+1;
if(my[vv]==-1) flag=true;
else
{
dx[my[vv]]=dy[vv]+1;
q.push(my[vv]);
}
}
}
}
if(flag==false) break;
memset(vis,0,sizeof(vis));
for(i=1;i<=nx;i++)
{
if(mx[i]==-1&&dfs(i))
ret++;
}
}
return ret;
}

int main()
{
int cas,i,j,numcas=0;
scanf("%d",&cas);
while(cas--)
{
int t;
scanf("%d",&t);
scanf("%d",&nx);
for(i=1;i<=nx;i++)
v[i].clear();
for(i=1;i<=nx;i++)
scanf("%d%d%d",&per[i].x,&per[i].y,&per[i].sp);
scanf("%d",&ny);
for(i=1;i<=ny;i++)
scanf("%d%d",&umb[i].x,&umb[i].y);
for(i=1;i<=nx;i++)
{
for(j=1;j<=ny;j++)
{
if(per[i].sp*t*per[i].sp*t>=(per[i].x-umb[j].x)*(per[i].x-umb[j].x)+(per[i].y-umb[j].y)*(per[i].y-umb[j].y))
v[i].push_back(j);
}
}
printf("Scenario #%d:\n",++numcas);
printf("%d\n\n",hkmatch());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: