还是二分图匹配,但是需要用到HKmatch优化。
HKmatch,多点同时开始找广增路,在稀疏图的时候提高了效率。
#include<bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define pb(a) push_back(a)
#define fir first
#define se second
typedef pair<int,int> pii;
const int maxn = 3005;
int vis[3005],vy[3005],n,m,v[maxn],times,vx[maxn],dx[maxn],dy[maxn];
pii a[maxn],b[maxn];
vector<int> g[3005];
int dfs(int u) {
int len = g[u].size();
for(int i = 0;i < len;i++) {
int v = g[u][i];
if(!vis[v] && dy[v] == dx[u]+1) {
vis[v] = 1;
if(!vy[v] || dfs(vy[v])) {
vy[v] = u;
vx[u] = v;
return 1;
}
}
}
return 0;
}
int HKmatch()
{
clr(vx,0);
clr(vy,0);
int ans = 0;
while(true)
{
int flag = 0;
queue<int> q;
memset(dx,0,sizeof(dx));
memset(dy,0,sizeof(dy));
for(int i = 1;i <= n;i++)
if(!vx[i]) q.push(i);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = 0;i < g[u].size();i++)
{
int v = g[u][i];
if(!dy[v])
{
dy[v] = dx[u]+1;
if(vy[v])
{
dx[vy[v]] = dy[v]+1;
q.push(vy[v]);
}
else flag = 1;
}
}
}
if(!flag) break;
clr(vis,0);
for(int i = 1;i <= n;i++)
if(!vx[i] && dfs(i))
ans++;
}
return ans;
}
int dis(int x1,int y1,int x2,int y2) {
int dd = (x2-x1)*(x2-x1);
dd += (y2-y1)*(y2-y1);
return dd;
}
int main() {
int t;
scanf("%d",&t);
for(int s = 1;s <= t;s++) {
for(int i = 1;i <= n;i++) g[i].clear();
clr(vy,0);
scanf("%d",×);
scanf("%d",&n);
for(int i = 1;i <= n;i++)
scanf("%d%d%d",&a[i].fir,&a[i].se,&v[i]);
scanf("%d",&m);
for(int i = 1;i <= m;i++) {
scanf("%d%d",&b[i].fir,&b[i].se);
for(int j = 1;j <= n;j++) {
int dd = dis(a[j].fir,a[j].se,b[i].fir,b[i].se);
//printf("%d==\n",n);
if((dd / (v[j]*v[j])) <= times*times) g[j].pb(i);
}
}
printf("Scenario #%d:\n%d\n\n",s,HKmatch());
}
}