二分匹配,建图,hk算法,然道匈牙利算法要退休了?
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define oo 0x3f3f3f3f
const int maxn = 3050;
using namespace std;
int t,n,m;
struct node
{
int x,y,speed;
};
struct edge
{
int u,v,next;
};
int head[maxn],tot;
edge e[maxn*maxn];
node umbrella[maxn], guest[maxn];
int cx[maxn],cy[maxn],dx[maxn],dy[maxn];
int vis[maxn];
bool can(node a, node b)
{
int dis,tt;
dis = (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
tt = a.speed*a.speed*t*t;
if(tt >= dis)return true;
return false;
}
void add(int u, int v)
{
e[tot].u = u;
e[tot].v = v;
e[tot].next = head[u];
head[u] = tot++;
}
int searchpath()//增广路一条
{
int dis = oo;
memset(dx, -1,sizeof(dx));
memset(dy, -1,sizeof(dy));
queue<int>Q;
for(int i = 1; i <= n; i++)
{
if(cx[i]==-1)
{
Q.push(i);
dx[i] = 0;
}
}
while(!Q.empty())
{
int u = Q.front();
Q.pop();
if(dx[u]>dis)break;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(dy[v]==-1)//如果这个点还未走过
{
dy[v] = dx[u]+1;
if(cy[v]==-1)dis = dy[v];//如果未匹配,则直接匹配
else//有了就反回回去
{
dx[cy[v]] = dy[v]+1;//匹配的那个点
Q.push(cy[v]);
}
}
}
}
return dis != oo;
}
int dfs(int u)
{
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(!vis[v]&&dx[u]+1 == dy[v])
{
vis[v] = 1;
if(cy[v]==-1||dfs(cy[v]))
{
cy[v] = u;
cx[u] = v;
return 1;
}
}
}
return 0;
}
int Maxpath()
{
int ret = 0;
memset(cx, -1,sizeof(cx));
memset(cy, -1,sizeof(cy));
while(searchpath())
{
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++)
if(cx[i]==-1)
ret += dfs(i);
}
return ret;
}
void Init()
{
memset(head, -1,sizeof(head));
tot = 0;
scanf("%d%d",&t,&n);
for(int i = 1; i <= n; i++)
{
scanf("%d%d%d",&guest[i].x,&guest[i].y,&guest[i].speed);
}
scanf("%d",&m);
for(int i = 1; i <= m; i++)
{
scanf("%d%d",&umbrella[i].x, &umbrella[i].y);
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if(can(guest[i],umbrella[j]))
{
add(i,j);
}
}
}
}
int main()
{
int t,ret;
scanf("%d",&t);
for(int ct = 1; ct <= t; ct++)
{
Init();
printf("Scenario #%d:\n%d\n\n",ct,Maxpath());
}
return 0;
}