这题目过的挺少的,看着吓人,这道题目一开始用最常用的匈牙利算法就超时,后来网上查了一下,原来给忘了二分匹配中还有一个Hopcroft-Carp的算法,直接找了个模版套了一下,1A,好开心
先讲一下题目的意思,第一行案例数,每个案例第一行 代表还有多少单位时间开始下雨,然后是 N个访客,接下来N行是 每个访客的位置(一维坐标平面内)和他的移动速度,接下来M行 代表雨伞数目,接下来M行表示各个雨伞的位置,问在下雨前 最多有多少人能够拿到雨伞(两个人不共用一把伞)
先给个模版把 模版不是我的 来自kuangbin大神 http://www.cnblogs.com/kuangbin/archive/2011/08/12/2135898.html
/**********************************************
二分图匹配(Hopcroft-Carp的算法)。
初始化:g[][]邻接矩阵
调用:res=MaxMatch(); Nx,Ny要初始化!!!
时间复杂大为 O(V^0.5 E)
适用于数据较大的二分匹配
***********************************************/
const int MAXN=3001;
const int INF=1<<28;
int g[MAXN][MAXN],Mx[MAXN],My[MAXN],Nx,Ny;
int dx[MAXN],dy[MAXN],dis;
bool vst[MAXN];
bool searchP()
{
queue<int>Q;
dis=INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i=0;i<Nx;i++)
if(Mx[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<Ny;v++)
if(g[u][v]&&dy[v]==-1)
{
dy[v]=dx[u]+1;
if(My[v]==-1) dis=dy[v];
else
{
dx[My[v]]=dy[v]+1;
Q.push(My[v]);
}
}
}
return dis!=INF;
}
bool DFS(int u)
{
for(int v=0;v<Ny;v++)
if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+1)
{
vst[v]=1;
if(My[v]!=-1&&dy[v]==dis) continue;
if(My[v]==-1||DFS(My[v]))
{
My[v]=u;
Mx[u]=v;
return 1;
}
}
return 0;
}
int MaxMatch()
{
int res=0;
memset(Mx,-1,sizeof(Mx));
memset(My,-1,sizeof(My));
while(searchP())
{
memset(vst,0,sizeof(vst));
for(int i=0;i<Nx;i++)
if(Mx[i]==-1&&DFS(i)) res++;
}
return res;
}
接下来是本题的代码,基本就是套模版,而且很多地方 用过匈牙利算法的一看就懂了,刚好过1000ms的代码,题目要求是3000ms,不过貌似有人在1000内的 好厉害
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#define ll long long
#define LL __int64
#define eps 1e-8
const ll INF=9999999999999;
using namespace std;
#define M 400000100
#define inf 0xfffffff
//vector<pair<int,int> > G;
//typedef pair<int,int> P;
//vector<pair<int,int>> ::iterator iter;
//
//map<ll,int>mp;
//map<ll,int>::iterator p;
vector<int>G[8000];
int mp[5012][5012];
int num[5012];
int lmarry[5012],rmarry[5012];
bool vis[5012];
int v[5012];
int dx[5012],dy[5012];
int dis[2][4]={0,-1,0,1,1,0,-1,0};
int n,m,k;
struct Node
{
int x,y;
}l[5012],r[5012];
void clear()
{
memset(lmarry,-1,sizeof(lmarry));
memset(rmarry,-1,sizeof(rmarry));
memset(vis,false,sizeof(vis));
memset(mp,0,sizeof(mp));
for(int i=0;i<=m;i++)
G[i].clear();
}
double distance(int i,int j)
{
return sqrt(double((l[i].x-r[j].x)*(l[i].x-r[j].x)+(l[i].y-r[j].y)*(l[i].y-r[j].y)));
}
bool detal()
{
queue<int>q;
memset(dx,0,sizeof(dx));
memset(dy,0,sizeof(dy));
int u,v;
bool flag=false;
for(int i=1;i<=m;i++)
if(lmarry[i]==-1)
q.push(i);
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=0;i<G[u].size();i++)
{
v=G[u][i];
if(!dy[v])
{
dy[v]=dx[u]+1;
if(rmarry[v]==-1)
flag=true;
else
{
dx[rmarry[v]]=dy[v]+1;
q.push(rmarry[v]);
}
}
}
}
return flag;
}
bool dfs(int x)
{
for(int i=0;i<G[x].size();i++)
{
int v=G[x][i];
if(dy[v]==dx[x]+1 && !vis[v])
{
vis[v]=true;
if(rmarry[v]==-1 || dfs(rmarry[v]))
{
rmarry[v]=x;
lmarry[x]=v;
return 1;
}
}
}
return 0;
}
int main(void)
{
int Case=0;
int t;
cin>>t;
while(t--)
{
printf("Scenario #%d:\n",++Case);
scanf("%d",&n);
scanf("%d",&m);
clear();
for(int i=1;i<=m;i++)
scanf("%d %d %d",&l[i].x,&l[i].y,&v[i]);
scanf("%d",&k);
for(int i=1;i<=k;i++)
scanf("%d %d",&r[i].x,&r[i].y);
for(int i=1;i<=m;i++)
{
for(int j=1;j<=k;j++)
if(v[i]*n>=distance(i,j))
G[i].push_back(j);
}
int ans=0;
while(detal())
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=m;i++)
if(lmarry[i]==-1)
{
if(dfs(i))
ans++;
}
}
printf("%d\n\n",ans);
}
}