您的位置:首页 > 其它

hdu2389-二分匹配HK算法

2017-07-13 16:33 302 查看
题意:就是将在t秒后下雨然后给你n个人的坐标和速度m把伞的坐标然后求最多可以有几个人拿到伞

题解思路:求出哪个人可以和哪把伞匹配后就是二分最大匹配但是用匈牙利算法肯定会超时那么此时就要用HK算法优化一下即可

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
const int mx = 3005;
const int inf = 0x3f3f3f3f;
int dx[mx],dy[mx],dis,n,m;
int vis[mx],x[mx],y[mx];
bool g[mx][mx];
double T;
struct pos{
double x,y,s;
}a[mx],b[mx];
bool search(){
queue<int>q;
dis = inf;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i = 0; i < n; i ++)
if(x[i] == -1){
q.push(i);
dx[i] = 0;
}
while(!q.empty()){
int u = q.front();
if(dx[u] > dis)    break;
q.pop();
for(int v = 0; v < m; v++){
if(g[u][v] && dy[v] == -1){
dy[v] = dx[u]+1;
if(y[v] == -1) dis = dy[v];  //如果已经可以匹配就不用增广下面的点先用了再说
else{
dx[y[v]] = dy[v]+1;    //如果已经匹配看下还能不能增广
q.push(y[v]);
}
}
}
}
return dis != inf; //判断是否有点可以增广如果不能就是inf
}
bool find(int u){
for(int v = 0; v < m; v++)
if(!vis[v]&&g[u][v]&&dy[v]==dx[u]+1){   //如果这个v是被u第一次就发现的
vis[v] = 1;
if(y[v]!=-1    &&dy[v] == dis)continue; //如果v已经被匹配并且这个v对应路径已经没办法增广了
if(y[v] == -1||find(y[v])){
x[u] = v;
y[v] = u;
return true;
}
}
return false;
}
int MaxMatch(){
int ans = 0;
memset(x,-1,sizeof(x));
memset(y,-1,sizeof(y));
while(search()){
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++)
if(x[i] == -1&&find(i)) ans++;
}
return ans;
}
double gettime(pos a,pos b){
return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2))/a.s;
}
void init(){
memset(g,0,sizeof(g));
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++){
double t = gettime(a[i],b[j]);
//    printf("%lf %lf\n",t,T);
if(t<=T){
g[i][j] = 1;
//cout<<"1"<<endl;
}
}
}
int main(){
int t;
scanf("%d",&t);
for(int casei = 1; casei <= t; casei++){
scanf("%lf",&T);
scanf("%d",&n);
for(int i = 0; i < n; i++)
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].s);
scanf("%d",&m);
for(int i = 0; i < m; i++)
scanf("%lf%lf",&b[i].x,&b[i].y);
init();
printf("Scenario #%d:\n",casei);
printf("%d\n\n",MaxMatch());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: