HDU-2389 Rain on your Parade 裸Hopcroft–Karp algorithm
来源:互联网 发布:富坚义博 知乎 编辑:程序博客网 时间:2024/05/23 21:56
http://acm.hdu.edu.cn/showproblem.php?pid=2389
题意:
nx个人 ny个伞 t时间内问最多有多少人能到达伞躲雨(一个伞只能容纳一个人,每个人有各自的速度)
模型:
二分图匹配 人匹配伞 把人能在t时间内到达的伞连边建立二分图 HK算法求最大匹配
#include<stdio.h>#include<iostream>#include<string.h>#include<vector>#include<queue>#include<algorithm>using namespace std;const int maxn = 3005;const int inf = 1<<30;int nx,ny,t;int dist; //最大分层数bool map[maxn][maxn],vis[maxn]; //二分图 寻找增广路时的标记数组int cx[maxn],cy[maxn]; //cx[i] 表示左集合i顶点所匹配到的右集合顶点序号 cy[i]表示右集合i顶点所匹配到的左集合顶点序号 int dx[maxn],dy[maxn]; //dx[i] 表示左集合i顶点的距离标号 dy[i] 表示右集合i顶点的距离标号 struct node{ int x,y,r;}man[maxn];struct node1{ int x,y;}unb[maxn];void readData(){ int dis; scanf("%d%d",&t,&nx); for( int i = 1; i <= nx; i ++ ){ scanf("%d%d%d",&man[i].x,&man[i].y,&man[i].r); man[i].r *= t; } scanf("%d",&ny); for( int i = 1; i <= ny; i ++ ){ scanf("%d%d",&unb[i].x,&unb[i].y); } for( int i = 1; i <= nx; i ++ ){ for( int j = 1; j <= ny; j ++ ){ dis = (man[i].x-unb[j].x)*(man[i].x-unb[j].x) + (man[i].y-unb[j].y)*(man[i].y-unb[j].y); if( dis <= man[i].r*man[i].r ) map[i][j] = true; else map[i][j] = false; } }}//Hopcroft-Karp算法 有点类似dinic 都是先对图BFS分层再沿层数DFS找增广路 //*************************************************************************** bool searchPath() //BFS 对二分图分层 { dist = inf; queue<int>que; memset( dx,-1,sizeof(dx) ); memset( dy,-1,sizeof(dy) ); for( int i = 1; i <= nx; i ++ ){ //找到x集合所有未被匹配的点压入队列中 if( cx[i] == -1 ){ que.push(i); dx[i] = 0; } } while( !que.empty() ){ int u = que.front(); que.pop(); if( dx[u] > dist ) //只分层到第一个找个的可匹配点层数 break; for( int v = 1; v <= ny; v ++ ) { if( map[u][v] && dy[v] == -1 ){ dy[v] = dx[u] + 1; if( cy[v] == -1 ) //找个一个可以匹配点 标记分层的层数 dist = dy[v]; else{ dx[cy[v]] = dy[v] + 1; que.push( cy[v] ); } } } } return dist != inf; }bool findPath( int u ) //沿着层数DFS { for( int v = 1; v <= ny; v ++ ){ if( map[u][v] && !vis[v] && dy[v] == dx[u] + 1 ){ vis[v] = true; if( cy[v] != -1 && dy[v] == dist ) //如果v已经有匹配了且v的层数为dist( 最大层数为dist 所以v原来匹配的不可能再匹配 ) continue; if( cy[v] == -1 || findPath( cy[v] ) ){ //如果v未匹配就跟u匹配v 否则看v原来匹配的是否还能跟其他的匹配 能就跟u匹配 不能就不匹配 cy[v] = u; cx[u] = v; return true; } } } return false;}int HK_MaxMatch(){ int ans = 0; memset( cx,-1,sizeof(cx) ); memset( cy,-1,sizeof(cy) ); while( searchPath() ){ //分层 + 判断是否还有未匹配点 memset( vis,0,sizeof(vis) ); for( int i = 1; i <= nx; i ++ ){ if( cx[i] == -1 ) ans += findPath(i); } } return ans;}//*************************************************************************** int main(){ //freopen("data.txt","r",stdin); int c,cas = 1; scanf("%d",&c); while( c-- ){ readData(); printf("Scenario #%d:\n%d\n",cas++,HK_MaxMatch() ); puts(""); } return 0;}
- HDU-2389 Rain on your Parade 裸Hopcroft–Karp algorithm
- hdu 2389 Rain on your Parade (二分图,Hopcroft-Karp)
- hdu 2389 Rain on your Parade(最大匹配,Hopcroft-Karp算法模版)
- hdu 2389 Rain on your Parade(二分图最大匹配,Hopcroft-Karp)
- HDU-2389 Rain on your Parade(二分图之Hopcroft-Karp算法)
- hdu2389 Rain on your Parade (最大匹配Hopcroft--Karp)
- Hopcroft-Karp 二分图HDU2389 Rain on your Parade
- HDU-2389-Rain on your Parade [二分匹配][Hopcroft-Carp]
- HDU 2389 Rain on your Parade(Hopcroft_Carp Algorithm)
- HDU2389-Rain on your Parade(二分图匹配Hopcroft-Karp算法)
- 【HDU】2389 Rain on your Parade 二分匹配 Hopcroft-Krap算法
- HDU 2389 Rain on your Parade (二分图匹配(Hopcroft-Carp的算法模板))
- hdu 2389 Rain on your Parade(二分匹配Hopcroft-Carp算法模版)
- HDU 2389 Rain on your Parade(Hopcroft-Carp算法模板)
- HDU 2389 Rain on your Parade(Hopcroft-Carp算法板子题)
- HDU 2389 Rain on your Parade(二分匹配+Hopcroft-Carp算法模板题)
- HDU 2389 Rain on your Parade //MAXMATCH
- Hdu 2389 Rain on your Parade
- 微信公众号开放接口推送图文信息教程
- ubuntu下命令安装与卸载软件方法
- MFC 多文档模板切换
- FAFU-1198 小三大作战 多重匹配
- HDU-1150 HK二分图最小点覆盖
- HDU-2389 Rain on your Parade 裸Hopcroft–Karp algorithm
- Linked List Cycle II
- HDU-2458 Kindergarten 最大完全子图(最大团)中顶点的个数
- Hopcroft-Karp算法 二分图最小路径覆盖
- memset以字节为单位操作
- 【装饰设计模式】写一个MyBufferedReader实现自己的ReadLine方法、增强BufferedReader的ReaderLine()
- HDU-4160 Doll 最小路径覆盖
- cf 359A 359B
- HDU-4160 Doll 匈牙利算法