大意:问最多有几个人能拿到雨伞
思路:这题算是裸题吧,但用匈牙利算法会超时,要用Hopcroft-Carp算法,我用的是kuangbin的板子,但没有解释,解释看这篇博客
#include<bits/stdc++.h>
#define maxn 3050
#define inf 0x3f3f3f3f
using namespace std;
struct node{
double x,y,v;
}p[maxn];
struct place{
double x,y;
}u[maxn];
int t,m,n,dis;
int cx[maxn],cy[maxn],dx[maxn],dy[maxn];
int vis[maxn];
vector<int> e[maxn];
double distance(node a,place b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool Searchp(){
queue<int> q;
dis=inf;
memset(dx,-1,sizeof dx);
memset(dy,-1,sizeof dy);
for(int i=1;i<=n;i++){
if(cx[i]==-1){
q.push(i);
dx[i]=0;
}
}
while(!q.empty()){
int now=q.front();
q.pop();
if(dx[now]>dis)break;
for(int i=0;i<e[now].size();i++){
int v=e[now][i];
if(dy[v]==-1){
dy[v]=dx[now]+1;
if(cy[v]==-1){
dis=dy[v];
}else{
dx[cy[v]]=dy[v]+1;
q.push(cy[v]);
}
}
}
}
return dis!=inf;
}
bool dfs(int u){
for(int i=0;i<e[u].size();i++){
int v=e[u][i];
if(!vis[v]&&dy[v]==dx[u]+1){
vis[v]=1;
if(cy[v]!=-1&&dy[v]==dis){
continue;
}
if(cy[v]==-1||dfs(cy[v])){
cx[u]=v;
cy[v]=u;
return true;
}
}
}
return false;
}
int Maxmatch(){
memset(cx,-1,sizeof cx);
memset(cy,-1,sizeof cy);
int res=0;
while(Searchp()){
memset(vis,0,sizeof vis);
for(int i=1;i<=m;i++){
if(cx[i]==-1&&dfs(i)){
res++;
}
}
}
return res;
}
int main(){
// freopen("in.txt","r",stdin);
int k,cases=1;
scanf("%d",&k);
while(k--){
for(int i=0;i<maxn;i++){
e[i].clear();
}
scanf("%d",&t);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].v);
}
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf",&u[i].x,&u[i].y);
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(p[i].v*t>=distance(p[i],u[j])){
e[i].push_back(j);
}
}
}
int ans=Maxmatch();
printf("Scenario #%d:\n%d\n\n",cases++,ans);
}
}