HDU-2389 Rain on your Parade 裸Hopcroft–Karp algorithm
2013-11-03 14:00
501 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2389
题意:
nx个人 ny个伞 t时间内问最多有多少人能到达伞躲雨(一个伞只能容纳一个人,每个人有各自的速度)
模型:
二分图匹配 人匹配伞 把人能在t时间内到达的伞连边建立二分图 HK算法求最大匹配
题意:
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
- HDU 2389 ——Rain on your Parade——————【Hopcroft-Karp求最大匹配、sqrt(n)*e复杂度】
- hdu 2389 Rain on your Parade (二分匹配 Hc 算法)
- hdu 2389 Rain on your Parade(二分最大匹配HK算法)
- Rain on your Parade HDU - 2389
- HDU 2389 Rain on your Parade //MAXMATCH
- 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【最大匹配】
- hdu 2389 Rain on your Parade
- HDU 2389 Rain on your Parade(二分匹配,Hopcroft-Carp算法)
- HDU 2389 Rain on your Parade(HK算法)
- HDU2389-Rain on your Parade-二分图匹配-ISAP
- HDU 2389 Rain on your Parade
- HDU 2389 Rain on your Parade (二分匹配)
- HDU - 2389 Rain on your Parade(Hopcroft Karp算法)
- HDU 2389 Rain on your Parade(H-C算法,二分图匹配)
- hdu 2389 Rain on your Parade 二分匹配 HK算法
- HDU 2389 Rain on your Parade / HUST 1164 4 Rain on your Parade