当前位置: 首页 > news >正文

HDU-2389 Rain on your Parade(二分图之Hopcroft-Karp算法)

题意:

N个人M把伞,T秒后下雨,给出每个人的坐标和跑路的速度以及伞的坐标,问在T秒内最多能有几个人能拿到伞(约束:每把伞只能一个人用)。(N,M <= 3000)

思路:

很容易看出来的最大匹配,但发现点的数量达到3000,而边的数量也随之达到3000*3000,而匈牙利算法的复杂度为O(N*M)[N是A部的点数,M是边数]。所以这里引出了一个复杂度为O(sqrt(N)*M)的Hopcroft-Karp算法,入门点击。


代码(模板):

#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 3005;
struct node
{
	int x, y, d;
} a[maxn];
vector<int> G[maxn];
int T, N, M;
int nx, ny;		//A部点数,B部点数 
int dx[maxn], dy[maxn], cx[maxn], cy[maxn];
//A部层次,B部层次,A部匹配的B部点,B部匹配的A部点 
int dis, vis[maxn];
queue<int> q;
bool BFS()
{
	memset(dx, -1, sizeof dx);
	memset(dy, -1, sizeof dy);
	while(!q.empty()) q.pop();
	dis = inf;
	for(int i = 1; i <= nx; ++i)
	if(cx[i] == -1) q.push(i);	//每次都以A部未匹配的点为起点 
	while(!q.empty())
	{
		int u = q.front(); q.pop();
		if(dx[u] > dis) break;	//寻诈增广路终止条件:第K层包含为匹配的B部顶点 
		for(int i = 0; i < G[u].size(); ++i)
		{
			int v = G[u][i];
			if(dy[v] == -1)
			{
				dy[v] = dx[u]+1;
				//确定当找到B部未匹配点时的层次 
				if(cy[v] == -1) dis = dy[v];
				else
				{
					//通过已匹配边直接寻到A部的点 
					dx[cy[v]] = dy[v]+1;
					q.push(cy[v]);
				}
			}
		}
	}
	return dis != inf;
}
int DFS(int cur)
{
	for(int i = 0; i < G[cur].size(); ++i)
	{
		int v = G[cur][i];
		if(!vis[v] && dy[v] == dx[cur]+1)
		{
			vis[v] = 1;
			//当第dis层的B部点不是未匹配点时,直接忽略(优化) 
			if(cy[v] != -1 && dy[v] == dis) continue;
			if(cy[v] == -1 || DFS(cy[v]))
			{
				cy[v] = cur;
				cx[cur] = v;
				return 1;
			}
		}
	}
	return 0;
}
int hopcroft_karp()
{
	memset(cx, -1, sizeof cx);
	memset(cy, -1, sizeof cy);
	int ans = 0;
	while(BFS())
	{
		memset(vis, 0, sizeof vis);
		for(int i = 1; i <= nx; ++i)
		if(cx[i] == -1) ans += DFS(i);
	}
	return ans;
}
int judge(int x1, int y1, int x2, int y2, int d)
{
	return (d*T*d*T) >= (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
void mapping()	//构图 
{
	int x, y;
	scanf("%d %d", &T, &M);
	for(int i = 1; i <= M; ++i)
	{
		G[i].clear();
		scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].d);
	}
	scanf("%d", &N);
	for(int i = 1; i <= N; ++i)
	{
		scanf("%d %d", &x, &y);
		for(int j = 1; j <= M; ++j)
		{
			if(judge(x, y, a[j].x, a[j].y, a[j].d))
			G[j].push_back(i);
		}
	}
}
int main()
{
	int tt; scanf("%d", &tt);
	for(int _ = 1; _ <= tt; ++_)
	{
		mapping();
		nx = M, ny = N;
		int ans = hopcroft_karp();
		printf("Scenario #%d:\n%d\n\n", _, ans);
	}
	return 0;
}

继续加油~

相关文章:

  • javascript实现 color颜色格式转换【 rgb和十六进制的转换】
  • HDU-4686 Arc of Dream(推公式+矩阵快速幂)
  • python之测试
  • Codeforces-557D Vitaly and Cycle(二分图染色)
  • POJ-1019 Number Sequence(思维题)
  • 【吾日三省吾身】2015.6.13-涅槃行动第二十六天
  • Codeforces Round #427 (Div. 2)-C. Star sky(二维前缀和)
  • sequioadb源码分析2
  • HDU-6058 Kanade's sum - 2017 Multi-University Training Contest - Team 3(思维+模拟链表)
  • PowerShell获取特定“描述”的虚拟机IP地址
  • HDU-6060 RXD and dividing - 2017 Multi-University Training Contest - Team 3(思维+最小斯坦纳树)
  • error while loading shared libraries错误处理
  • POJ-3270 Cow Sorting(贪心+置换)
  • php对gzip文件或者字符串解压实例参考
  • POJ-1637 Sightseeing tour(通过网络流判定混合图的欧拉回路)
  • 【剑指offer】让抽象问题具体化
  • CEF与代理
  • happypack两次报错的问题
  • Java IO学习笔记一
  • Js基础知识(一) - 变量
  • Kibana配置logstash,报表一体化
  • markdown编辑器简评
  • react 代码优化(一) ——事件处理
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • vue总结
  • Vultr 教程目录
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 判断客户端类型,Android,iOS,PC
  • 数据可视化之 Sankey 桑基图的实现
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 如何在招聘中考核.NET架构师
  • ​secrets --- 生成管理密码的安全随机数​
  • ​卜东波研究员:高观点下的少儿计算思维
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (Python第六天)文件处理
  • (安卓)跳转应用市场APP详情页的方式
  • (二)c52学习之旅-简单了解单片机
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (转)ABI是什么
  • .java 9 找不到符号_java找不到符号
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .Net程序帮助文档制作
  • .NET是什么
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...