题目:http://acm.hdu.edu.cn/showproblem.php?pid=2389
直接找的一个HK算法模板。
下面是 AC代码:
//该算法的精髓在于同时找多条增广路进行反转。
//我们先用BFS找出可能的增广路,这里用到BFS层次搜索的概念,
//记录当前结点在第几层,用于后面DFS沿增广路反转时用,
//然后再用DFS沿每条增广路反转。这样不停地找,直至无法找到增广路为止。
#include<cstring> //HK算法。。
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=3005;
int n,m;
struct Pos{
int x,y;
}man[maxn],umbr[maxn];
vector<int> child[maxn];
int speed[maxn];//人的速度
int cx[maxn],cy[maxn];//集合X Y的匹配值
int distx[maxn],disty[maxn];//记录距离
bool bfs(){
bool flag=false;
memset(distx,0,sizeof(distx));//距离初始为0
memset(disty,0,sizeof(disty));
queue<int> que;
for(int i=1;i<=n;i++)//把X集合中 所有未匹配的加入队列
if(cx[i]==-1)
que.push(i);
while(!que.empty())//集合非空
{
int x=que.front();
que.pop();
for(int i = 0 ; i < child[ x ].size() ; i++ )//所有以i为起点的边
{
int y = child[ x ][ i ];
if( !disty[ y ] )//该边未被使用
{
disty[ y ]=distx[ x ] + 1;//距离+1
if(cy[ y ] == -1) flag=true;//该点未被使用可以增加匹配
else
{
distx[ cy[ y ] ]= disty[ y ] + 1;
que.push( cy[ y ] );
}
}
}
}
return flag;
}
bool dfs(int x){//寻找增广路
for(int i=0;i<child[x].size();i++)//枚举所有以i为起点的边
{
int y=child[x][i];
if(disty[ y ] == distx[ x ]+1)//距离刚好为1表明相连
{
disty[ y ] = 0;
if(cy[ y ] == -1 || dfs( cy[ y ] ))//找到一条增广路
{
cx[ x ] = y ; cy[ y ] = x;//保存匹配值
return true;
}
}
}
return false;
}
int Hopcroft_Karp(){
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
int ans=0;
while(bfs())//如果距离更新成功,X集合中每一个点找一次增广路
{
for(int i=1;i<=n;i++)
if(cx[i]==-1 && dfs(i))
ans++;
}
return ans;
}
double dis(int i,int j){
return sqrt( (double)(man[i].x-umbr[j].x)*(man[i].x-umbr[j].x)+ (man[i].y-umbr[j].y)*(man[i].y-umbr[j].y) );
}
int main(){
int t,cas=0,time;
scanf("%d",&t);
while(t--){
scanf("%d%d",&time,&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&man[i].x,&man[i].y,&speed[i]);
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d%d",&umbr[i].x,&umbr[i].y);
for(int i=0;i<=n;i++)
child[i].clear();
for(int i=1;i<=n;i++)//能够在下雨前拿到伞的建一条边
for(int j=1;j<=m;j++)
if(speed[i]*time >= dis(i,j))
child[i].push_back(j);
printf("Scenario #%d:\n",++cas);
printf("%d\n",Hopcroft_Karp());
printf("\n");
}
}