标签:des style http io ar color os sp for
对应HDU题目:点击打开链接
| Time Limit: 3000MS | Memory Limit: 165535KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
Sample Input
2 1 2 1 0 3 3 0 3 2 4 0 6 0 1 2 1 1 2 3 3 2 2 2 2 4 4
Sample Output
Scenario #1: 2 Scenario #2: 2
Source
题意:在一个二维坐标系上有n个人和m把伞,每个人都有自己的移动速度,问最多有多少人可以再t min内移动到不同的雨伞处(不允许两个人共用一把伞)。
思路:很明显是二分图的最大匹配问题,用普通DFS,BFS匈牙利算法妥当TLE,之后学了Hopcroft-Karp算法后回来再做;
有点奇怪的是用邻接矩阵无论是效率或空间都比邻接表或vector要好。。。
贴上邻接表代码:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#define ms(x,y) memset(x,y,sizeof(x))
const int MAXN=3000+10;
const int MAX=9000000+10;
const int INF=1<<30;
using namespace std;
int time,n,m;
int speed[MAXN];
int head[MAXN];
int vis[MAXN];
int dx[MAXN];
int dy[MAXN];
int link_l[MAXN];
int link_r[MAXN];
int dis;
struct Edge
{
int v,next;
}E[MAX];
struct COOR
{
int x,y;
}N[MAXN], M[MAXN];
bool Search()
{
queue<int>q;
dis = INF;
ms(dx, -1);
ms(dy, -1);
for(int i = 0; i<n; i++)
if(link_r[i] == -1){//未匹配点入队,该点层次为0
q.push(i);
dx[i] = 0;
}
while(!q.empty())
{
int u = q.front();
q.pop();
if(dx[u] > dis) break;//层次大于该次搜索最小增广路层次,退出
for(int i = head[u]; i != -1; i = E[i].next){
int v = E[i].v;
if(dy[v] == -1){//v是未匹配点
dy[v] = dx[u] + 1;
if(link_l[v] == -1) dis = dy[v];//找到一条最小增广路
else{
dx[link_l[v]] = dy[v] + 1;
q.push(link_l[v]);
}
}
}
}
return dis != INF;
}
int dfs(int u)
{
for(int i=head[u]; i != -1; i = E[i].next){
int v = E[i].v;
if(!vis[v] && dy[v] == dx[u] + 1){
vis[v] = 1;
if(link_l[v] != -1 && dy[v] == dis) continue;//层次(也就是增广路径的长度)大于本次查找的dis,是searchP被break的情况,也就是还不确定是否是增广路径,只有等再次调用searchP()在判断。
if(link_l[v] == -1 || dfs(link_l[v])){
link_l[v] = u;
link_r[u] = v;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int res = 0;
ms(link_l, -1);
ms(link_r, -1);
while(Search())
{
ms(vis, 0);
for(int i=0; i<n; i++)
if(link_r[i] == -1) res += dfs(i);
}
return res;
}
int main()
{
//freopen("in.txt","r",stdin);
int T, w = 0;;
scanf("%d", &T);
while(T--)
{
ms(head, -1);
int size = 0;
scanf("%d%d", &time, &n);
for(int i=0; i<n; i++)
scanf("%d%d%d", &N[i].x, &N[i].y, &speed[i]);
scanf("%d", &m);
for(int i=0; i<m; i++)
scanf("%d%d", &M[i].x, &M[i].y);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if((N[i].x - M[j].x) * (N[i].x - M[j].x) + (N[i].y - M[j].y) * (N[i].y - M[j].y) <= time * speed[i] * time * speed[i]){
E[size].v = j;
E[size].next = head[i];
head[i] = size++;
}
}
}
printf("Scenario #%d:\n%d\n\n", ++w, MaxMatch());
}
return 0;
}
二分图最大匹配hopcroft-karp算法——HDU 2389
标签:des style http io ar color os sp for
原文地址:http://blog.csdn.net/u013351484/article/details/41944745