HDU2389---Rain on your Parade (二分图匹配-HK算法)
来源:互联网 发布:mac开发网站 编辑:程序博客网 时间:2024/05/16 07:27
题目来源:https://vjudge.net/problem/HDU-2389
题意
在一个露天party里,宾客们在狂欢,还有ts时间将要下雨,现场有m个人,地上有n个雨伞,各自有着不同的坐标,人有着各自的奔跑速度,一个伞只能够容纳一个人,问, 有多少个人可以不被雨淋湿。
思路
m个人,n把伞,典型的匹配问题,只要能跑到的就说明人和该伞有关系,然后就是二分匹配,但是普通的二分匹配会超时(时间复杂度是O(VE)),所以要用到二分匹配的HK算法(同时找到多条增广轨,时间复杂度O(V^0.5*E)),来优化整个匹配过程。
比较好的博客(HK算法):
http://files.cnblogs.com/files/liuxin1.pdf
代码
#include<cmath>#include<queue>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;const double eps=1e-6;int m,n,limit;bool mp[3000+10][3000+10];bool vis[3000+10];int linkX[3000+10],linkY[3000+10];//记录该点已经被谁连接了int depthX[3000+10],depthY[3000+10];//记录下每一个点的深度struct people{ double x,y,v;} p[3000+10];struct un{ double x,y;} s[3000+10];double dis(double x,double y,double x2,double y2){ return sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));}bool seachAP(){ limit=INF; queue<int> q; memset(depthX,-1,sizeof(depthX)); memset(depthY,-1,sizeof(depthY)); for(int i=1; i<=m; i++) { if(linkX[i]==-1)//把尚未匹配的假如队列,一个一个用深度标记之后,y利用dfs一起匹配,这是优化的地方 { q.push(i); depthX[i]=0; } } while(!q.empty()) { int w=q.front(); q.pop(); if(depthX[w]>limit) break;//如果找到了能够匹配的,就退出,但是有人会说为啥不在找到的时候直接退出,因为要标记所有长度深度不大于limit的组合 for(int i=1; i<=n; i++) { if(mp[w][i]&&depthY[i]==-1) { depthY[i]=depthX[w]+1; if(linkY[i]==-1) { limit=depthY[i];//limit赋值 } else { depthX[linkY[i]]=depthY[i]+1; q.push(linkY[i]);//增广路 } } } } return limit!=INF;}bool dfs(int x){ for(int i=1; i<=n; i++) { if(!vis[i]&&mp[x][i]&&depthY[i]==depthX[x]+1) { vis[i]=1; if(linkY[i]!=-1&&depthY[i]==limit) continue; if(linkY[i]==-1||dfs(linkY[i])) { linkX[x]=i; linkY[i]=x; return 1; } } } return 0;}int main(){ int T,cases=1; scanf("%d",&T); while(T--) { double t; scanf("%lf",&t); scanf("%d",&m); for(int i=1; i<=m; i++) { scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].v); } scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%lf%lf",&s[i].x,&s[i].y); } memset(mp,0,sizeof(mp)); for(int i=1; i<=m; i++) { for(int j=1; j<=n; j++) { double d=dis(p[i].x,p[i].y,s[j].x,s[j].y); if(d/p[i].v-t<eps) { mp[i][j]=1; } } } int res=0; memset(linkX,-1,sizeof(linkX)); memset(linkY,-1,sizeof(linkY)); while(seachAP()) { memset(vis,0,sizeof(vis)); for(int i=1; i<=m; i++) { if(linkX[i]==-1&&dfs(i)) { res++; } } } printf("Scenario #%d:\n",cases++); printf("%d\n\n",res); }}
阅读全文
0 0
- HDU2389 Rain on your Parade(二分图匹配 ,HK算法 )
- HDU2389---Rain on your Parade (二分图匹配-HK算法)
- hdu2389 Rain on your Parade【二分图最大匹配-HK算法】
- HDU2389 Rain on your Parade 【二分图最大匹配+HK算法】
- Hdu2389 Rain on your Parade (HK二分图最大匹配)
- hdu2389 Rain on your Parade--HK算法 & 最大匹配数
- HDU2389 Rain on your Parade(HK算法)
- HDU2389-Rain on your Parade(二分图匹配Hopcroft-Karp算法)
- hdu2389 Rain on your Parade(二分匹配hopcroft-carp算法)
- hdu 2389 Rain on your Parade 二分匹配 HK算法
- 【二分匹配】 HDU 2389 Rain on your Parade HK算法
- HDU2389 Rain on your Parade 二分图匹配——Hopcroft_Karp算法
- HDU2389-Rain on your Parade(二分图匹配bfs模板)
- hdu 2389 Rain on your Parade 二分图匹配+HK算法
- hdu 2389 Rain on your Parade(二分最大匹配HK算法)
- HDU 2389Rain on your Parade (HK二分图)
- HDU2389 Rain on your Parade 二分匹配 Hopcroft-Carp的算法+模版
- Hopcroft-Karp 二分图HDU2389 Rain on your Parade
- Hadoop(3-2)- Yarn 调度器Scheduler详解
- linux编程---信号中断处理
- JS操作DOM元素属性和方法
- HDU 1257 最少拦截系统
- SAP算法总结
- HDU2389---Rain on your Parade (二分图匹配-HK算法)
- Longest Ordered Subsequence 【poj-2533】【动态规划-最长上升子序列】
- DBCC
- JS随机打乱数组的方法小结
- HDU 6092 Rikka with Subset(题解解释)
- JNI调用c++函数,该函数的参数是结构体(——对象的传递)
- Bellovin -HDU5487
- Vue.js教程: 构建一个预渲染SEO友好的应用示例
- hdu6090_2017 Multi-University Training Contest