Way Selection【二分圖最大匹配】

題意

小杉家族r個人正在一片空地上散步,突然,外星人來了……
留給小杉家族脫逃的時間只有t秒,每個小杉都有一個跑的速度v
總共有a個傳送點,小杉們必須在t秒內到達傳送點才能脫逃
當一個小杉進入一個傳送點以後,該傳送點就會消失
現在請你安排一種方案,使脫逃的小杉儘可能的多

分析

r個人是X集合,a個傳送點是Y集合。如果第i個人能在t時間內到達第j個傳送點,則ri向aj連邊。最後求最大匹配

參考代碼

#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long
#define in rad()
inline int rad(){
	int x=0,f=1;char c=getchar();while(c>'9'||c<'0')c=getchar();
	if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-48,c=getchar();
	return x*f;
}
const int maxn=1e3+10;
const int maxm=4e5+100;
const int inf=1e9;
int r,a,t;
int mp[maxn][maxn],vis[maxn],match[maxn];
double x[maxn],y[maxn];
int ok(double xx,double yy,double v,int k){
	double len=v*t;
	double dis=sqrt((xx-x[k])*(xx-x[k]) + (yy-y[k])*(yy-y[k]));
	return len>=dis;
}
int find(int x){
	for(int i=1;i<=r;i++)
		if(mp[x][i] && !vis[i]){
			vis[i]=1;
			if(match[i]==-1 || find(match[i])){
				match[i]=x;return 1;
			}
		}
	return 0;
}
int km(){
	int ans=0;
	memset(match,-1,sizeof(match));
	for(int i=1;i<=a;i++){
		memset(vis,0,sizeof(vis));
		ans+=find(i);
	}
	return ans;
}
int main(){
	r=in;a=in;t=in;
	for(int i=1;i<=a;i++)
		scanf("%lf%lf",x+i,y+i);
	for(int i=1;i<=r;i++){
		double tx,ty,v;
		scanf("%lf%lf%lf",&tx,&ty,&v);
		for(int j=1;j<=a;j++)
			if(ok(tx,ty,v,j))mp[j][i]=1;
	}	
	cout<<km();
	return 0;
}	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章