T个测试用例, 时间time, n个人,接下来n行是坐标 和 每个人的速度 v。 m,接下来m行是 雨伞的坐标。
问time时间完就会下雨,这n个人最多有多少能跑到雨伞下。 每把雨伞只能有一个人。
二分图最大匹配 Hopcroft-Karp优化模版题
这个模版就是你只要往里面加可以连(匹配)的边,然后调用 MaxMatch()就行
代码语言:javascript复制#include <bits/stdc .h>
using namespace std;
const int MAXN = 3010;
const int MAXM = 3010*3010;
const int INF = 0x3f3f3f3f;
struct Edge {
int v;
int next;
} edge[MAXM];
struct node {
double x, y;
double v;
} a[MAXN], b[MAXN];
int nx, ny;
int cnt;
int t;
int dis;
int first[MAXN];
int xlink[MAXN], ylink[MAXN]; /*xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。*/
int dx[MAXN], dy[MAXN]; /*dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号*/
int vis[MAXN]; //寻找增广路的标记数组
void init() {
cnt = 0;
memset(first, -1, sizeof(first));
memset(xlink, -1, sizeof(xlink));
memset(ylink, -1, sizeof(ylink));
}
void read_graph(int u, int v) {
edge[cnt].v = v;
edge[cnt].next = first[u], first[u] = cnt ;
}
int bfs() {
queue<int> q;
dis = INF;
memset(dx, -1, sizeof(dx));
memset(dy, -1, sizeof(dy));
for(int i = 0; i < nx; i ) {
if(xlink[i] == -1) {
q.push(i);
dx[i] = 0;
}
}
while(!q.empty()) {
int u = q.front();
q.pop();
if(dx[u] > dis) break;
for(int e = first[u]; e != -1; e = edge[e].next) {
int v = edge[e].v;
if(dy[v] == -1) {
dy[v] = dx[u] 1;
if(ylink[v] == -1) dis = dy[v];
else {
dx[ylink[v]] = dy[v] 1;
q.push(ylink[v]);
}
}
}
}
return dis != INF;
}
int find(int u) {
for(int e = first[u]; e != -1; e = edge[e].next){
int v = edge[e].v;
if(!vis[v] && dy[v] == dx[u] 1) {
vis[v] = 1;
if(ylink[v] != -1 && dy[v] == dis) continue;
if(ylink[v] == -1 || find(ylink[v])){
xlink[u] = v, ylink[v] = u;
return 1;
}
}
}
return 0;
}
int MaxMatch() {
int ans = 0;
while(bfs()) {
memset(vis, 0, sizeof(vis));
for(int i = 0; i < nx; i ) if(xlink[i] == -1) {
ans = find(i);
}
}
return ans;
}
double dist(const node a, const node b) {
return sqrt((a.x-b.x)*(a.x-b.x) (a.y-b.y)*(a.y-b.y));
}
void read_case() {
init();
int Time;
scanf("%d", &Time);
scanf("%d", &nx);
for(int i = 0; i < nx; i ) {
scanf("%lf%lf%lf", &a[i].x, &a[i].y, &a[i].v);
}
scanf("%d", &ny);
for(int i = 0; i < ny; i ) {
scanf("%lf%lf", &b[i].x, &b[i].y);
}
for(int i = 0; i < nx; i ) {
for(int j = 0; j < ny; j ) {
double limit = a[i].v*Time;
double s = dist(a[i], b[j]);
if(s <= limit) read_graph(i, j);
}
}
}
void solve() {
read_case();
int ans = MaxMatch();
printf("%dnn", ans);
}
int main() {
int T, times = 0;
scanf("%d", &T);
while(T--) {
printf("Scenario #%d:n", times);
solve();
}
return 0;
}