http://acm.hdu.edu.cn/showproblem.php?pid=2389
经典求最大匹配题,数据范围过大,匈牙利算法超时
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
/* *******************************
* 二分图匹配(Hopcroft-Carp算法)
* 复杂度O(sqrt(n)*E)
* 邻接表存图,vector实现
* vector先初始化,然后假如边
* uN 为左端的顶点数,使用前赋值(点编号0开始)
*/
const int MAXN = 3030;
const int INF = 0x3f3f3f3f;
vector<int>G[MAXN];
int uN;
int Mx[MAXN],My[MAXN];
int dx[MAXN],dy[MAXN];
int dis;
bool used[MAXN];
bool SearchP()
{
queue<int>Q;
dis = INF;
memset(dx,-1,sizeof(dx));
memset(dy,-1,sizeof(dy));
for(int i = 0 ; i < uN; 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;
int sz = G[u].size();
for(int i = 0;i < sz;i++)
{
int v = G[u][i];
if(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)
{
int sz = G[u].size();
for(int i = 0;i < sz;i++)
{
int v = G[u][i];
if(!used[v] && dy[v] == dx[u] + 1)
{
used[v] = true;
if(My[v] != -1 && dy[v] == dis)continue;
if(My[v] == -1 || DFS(My[v]))
{
My[v] = u;
Mx[u] = v;
return true;
}
}
}
return false;
}
int MaxMatch()
{
int res = 0;
memset(Mx,-1,sizeof(Mx));
memset(My,-1,sizeof(My));
while(SearchP())
{
memset(used,false,sizeof(used));
for(int i = 0;i < uN;i++)
if(Mx[i] == -1 && DFS(i))
res++;
}
return res;
}
struct Point
{
int x,y,s;
void input1()
{
scanf("%d%d%d",&x,&y,&s);
}
void input2()
{
scanf("%d%d",&x,&y);
}
};
int dis2(Point a,Point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
Point p1[MAXN],p2[MAXN];
int main()
{
int T;
int t;
int iCase = 0;
int n,m;
scanf("%d",&T);
while(T--)
{
iCase++;
scanf("%d",&t);
scanf("%d",&n);
for(int i = 0;i < n;i++)
p1[i].input1();
scanf("%d",&m);
for(int i = 0;i < m;i++)
p2[i].input2();
for(int i = 0;i < n;i++)
G[i].clear();
uN = n;
for(int i = 0;i < n;i++)
for(int j = 0;j < m;j++)
if(dis2(p1[i],p2[j]) <= p1[i].s*p1[i].s*t*t)
G[i].push_back(j);
printf("Scenario #%d:\n",iCase);
printf("%d\n\n",MaxMatch());
}
return 0;
}