Test instructions: Give some people and some umbrella coordinates, then everyone has a certain speed, and how much time will rain, ask how many people can get an umbrella. Analysis: Test instructions is very clear, can use each person and the umbrella to judge whether can achieve, if can establish a connection. But the data of the problem is quite large, the first use of the Hungarian algorithm decisive tle, and then Baidu a bit found there is aHopcroft-karp algorithm But this algorithm on-line description of the very few, and are said to be more ambiguous, but fortunately found a relatively good courseware, read a morning finally some understand how to go, was looking for an augmented road, this is to find all the augmented road, and using BFS to layered, looks taller, although I still do not understand how to reduce the complexity (the submission really does not time out) .... It's a little slow to understand.
Courseware Connection :
#include <stdio.h>
#include <string.h>
#include <queue>
usingnamespaceStd
Const intMAXN =3005;
ConstintOO = 1e9+7;
structpoint{intx, Y, V;} P[MAXN], um;
BOOLOK (Point A, point B,intV
{///determine whether the two point is within the legal range, that is, the next Yuqian can reach
intLen = (a.x-b.x) * (a.x-b.x) + (A.Y-B.Y) * (A.Y-B.Y);
if(Len > V*v)
returnfalse;
returntrue;
}
structedge{intV, Next;} E[MAXN*MAXN];
intHEAD[MAXN], CNT;
voidAddedge (intUintV
{///adjacency table, points more, not good open adjacency matrix
E[CNT].V = v;
E[cnt].next = Head[u];
Head[u] = cnt++;
}
BOOLUSED[MAXN];
intMX[MAXN], MY[MAXN];///The matched endpoint of the record, 0 indicates an unmatched
intDX[MAXN], DY[MAXN];///when a BFS is layered, the record point is in the same layer, 1 means not layered
intNx, Ny, depth;///NX Personal, NY take umbrella, depth record the depth of layering
BOOLBFS ()///if you find that Y has an augmented path on this side, return 1, or 0.
{
queue<int> Q; depth = oo;
memset (DX,-1,sizeof(DX));
memset (DY,-1,sizeof(DY));
for(intI=1; i<=nx; i++)
{
if(Mx[i] = =false)
{
Dx[i] =0;
Q.push (i);
}
}
while(Q.size ())
{
intx = Q.front (); Q.pop ();
if(Dx[x] > depth) Break;///We 've found the augmented path, no need to look for the lower
for(intJ=HEAD[X]; j!=-1; J=e[j].next)
{
inty = e[j].v;
if(Dy[y] = =-1)
{
Dy[y] = Dx[x] +1;
if(My[y] = =false)
depth = Dy[y];
Else
{
dx[My[y]] = Dy[y] +1;
Q.push (My[y]);
}
}
}
}
if(depth = = oo)
returnfalse;
returntrue;
}
BOOLFind (intI
{
for(intJ=head[i]; j!=-1; J=e[j].next)
{
intv = e[j].v;
if(!used[v] && dx[i] = = dy[v]-1)
{
USED[V] =true;
if(My[v] && dy[v] = = depth)
Continue;///not on the next level because the lower layer has not been augmented
if( ! MY[V] | | Find (My[v]))
{
MY[V] = i;
Mx[i] = v;
returntrue;
}
}
}
returnfalse;
}
intKarp ()
{
intAns =0;
memset (Mx,false,sizeof(Mx));
memset (My,false,sizeof(My));
while(BFS () = =true)
{///If there is an augmented path
memset (Used,false,sizeof(used));
for(intI=1; i<=nx; i++)
{
if( ! Mx[i] && Find (i) = =true)
ans++;
}
}
returnAns
}
intMain ()
{
intT, t=1;
scanf"%d", &t);
while(t--)
{
intI, J, time;
scanf"%d%d", &time, &NX);
memset (Head,-1,sizeof(Head));
CNT =0;
for(i=1; i<=nx; i++)
scanf"%d%d%d", &p[i].x, &p[i].y, &P[I].V);
scanf"%d", &ny);
for(i=1; i<=ny; i++)
{
scanf"%d%d", &um.x, &UM.Y);
for(j=1; j<=nx; J + +)
{
if(OK (P[j], um, p[j].v*time))
Addedge (J, I);
}
}
intans = Karp ();
printf"Scenario #%d:\n", t++);
printf"%d\n\n", ans);
}
return0;
}
F-rain on your parade-hdu 2389 (binary graph matching, HK algorithm)