大意:给定时间t,并且n个人的坐标,然后有伞的坐标求最少有多少人不被淋湿。
hk算法模板(O(V^0.5*E)),匈牙利算法复杂度(O(V*E))。
#include<map>
#include<queue>
#include<cmath>
#include<cstdio>
#include<stack>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 0x3f3f3f3f
#define eps 1e-8
#include<vector>
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
using namespace std;
struct node{
int x,y,p;
}q[3601];
struct no{
int xx,yy;
}qq[3601];
int mp[3601][3601],cx[3600],cy[3600],dx[3600],dy[3600];
int cro[3601],n,m,DIS;
bool vis[3601];
double dis(node a,no b){
return sqrt( (a.x-b.xx)*(a.x-b.xx)+(a.y-b.yy)*(a.y-b.yy) );
}
int finde(int u)
{
for(int v=0;v<m;v++)
{
if(!vis[v]&&mp[u][v]&&dy[v]==dx[u]+1)
{
vis[v]=1;
if(cy[v]!=-1&&dy[v]==DIS)
continue;
if(cy[v]==-1||finde(cy[v]))
{
cy[v]=u;cx[u]=v;
return 1;
}
}
}
return 0;
}
bool serp()
{
queue<int> Q;
DIS=inf;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=0;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 v=0;v<m;v++)
{
if(mp[u][v]&&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!=inf;
}
int MaxMatch(){
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
int res = 0;
while(serp()){
memset(vis,false,sizeof(vis));
for(int i = 0;i < n;++ i){
if(cx[i]==-1&&finde(i))
res++;
}
}
return res;
}
int main()
{
int i,j,k,cla,t;
scanf("%d",&cla);
for(int zu = 1;zu <= cla ;++ zu){
scanf("%d%d",&t,&n);
for(i = 0;i < n;++ i){
scanf( "%d%d%d",&q[i].x,&q[i].y,&q[i].p );
}
scanf("%d",&m);
for(i = 0;i < m;++ i){
scanf( "%d%d",&qq[i].xx,&qq[i].yy);
}
memset(mp,0,sizeof(mp));
int sum = 0;
for(i = 0;i < n;++ i){
bool bj = false;
for(j = 0;j < m;++ j){
double tmp = dis(q[i],qq[j]);
if(dis(q[i],qq[j])/q[i].p - t <= eps){
mp[i][j] = 1;
bj = true;
}
}
if(bj)
sum++;
}
printf("Scenario #%d:\n%d\n\n",zu,MaxMatch());
}
return 0;
}