Hopcroft-Karp算法

该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法。

原理

为了降低时间复杂度,可以在增广匹配集合M时,每次寻找多条增广路径。这样就可以进一步降低时间复杂度,可以证明,算法的时间复杂度可以到达O(n^0.5*m),虽然优化不了多少,但在实际应用时,效果还是很明显的。

基本算法

该算法主要是对匈牙利算法的优化,在寻找增广路径的时候同时寻找多条不相交的增广路径,形成极大增广路径集,然后对极大增广路径集进行增广。在寻找
增广路径集的每个阶段,找到的增广路径集都具有相同的长度,且随着算法的进行,增广路径的长度不断的扩大。可以证明,最多增广n^0.5次就可以得到最大
匹配。

算法流程

(1)从G=(X,Y;E)中取一个初始匹配。

(2)若X中的所有顶点都被M匹配,则表明M为一个完美匹配,返回;否则,以所有未匹配顶点为源点进行一次BFS,标记各个点到源点的距离。

(3)在满足dis[v] = dis[u] + 1的边集<v,u>中,从X中找到一个未被M匹配的顶点x0,记S = {x0},T = ¢。

(4)若N(S) = T,则表明当前已经无法得到更大匹配,返回;否则取一y0∈N(S) - 。

(5)若y0已经被M匹配则转步骤(6),否则做一条x0->y0的M-增广路径P(x0,y0),取M = M△P(x0,y0)。

(6)由于y已经被M匹配,所以M中存在一条边(y0,z0)去S = S∪ {z0},T = T∪{y0},转步骤(2)。

算法具体时间与分析

在寻找增广路径中可以对X中的每个未匹配的顶点进行BFS,BFS时对每个顶点维护一个距离编号dx[nx],dy[ny],如果某个Y中的节点为
未匹配点,则找到一条增广路径。BFS结束后找到了增广路径集。然后利用DFS与匈牙利算法类似的方法对每条增广路进行增广,这样就可以找到最大匹配。

F - Rain on your Parade

Time Limit:3000MS     Memory Limit:165535KB     64bit IO Format:%I64d & %I64u

Appoint description:
 

Description

You’re giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It’s a warm, sunny evening, and a soothing wind sends fresh, salty air from the sea. The evening is progressing just as you had imagined. It could be the perfect end of a beautiful day.
But nothing ever is perfect. One of your guests works in
weather forecasting. He suddenly yells, “I know that breeze! It means
its going to rain heavily in just a few minutes!” Your guests all wear
their best dresses and really would not like to get wet, hence they
stand terrified when hearing the bad news.

You have prepared a few umbrellas which can protect a few of
your guests. The umbrellas are small, and since your guests are all
slightly snobbish, no guest will share an umbrella with other guests.
The umbrellas are spread across your (gigantic) garden, just like your
guests. To complicate matters even more, some of your guests can’t run
as fast as the others.

Can you help your guests so that as many as possible find an umbrella before it starts to pour?

Given the positions and speeds of all your guests, the
positions of the umbrellas, and the time until it starts to rain, find
out how many of your guests can at most reach an umbrella. Two guests do
not want to share an umbrella, however.

 

Input

The input starts with a line containing a single integer, the number of test cases.

Each test case starts with a line containing the time t in
minutes until it will start to rain (1 <=t <= 5). The next line
contains the number of guests m (1 <= m <= 3000), followed by m
lines containing x- and y-coordinates as well as the speed si in units
per minute (1 <= s i <= 3000) of the guest as integers,
separated by spaces. After the guests, a single line contains n (1
<= n <= 3000), the number of umbrellas, followed by n lines
containing the integer coordinates of each umbrella, separated by a
space.

The absolute value of all coordinates is less than 10000.
 

Output

For each test case, write a line containing “Scenario #i:”, where i is
the number of the test case starting at 1. Then, write a single line
that contains the number of guests that can at most reach an umbrella
before it starts to rain. Terminate every test case with a blank line.
 

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

 
#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<math.h>
using namespace std;
#define eps 1e-6 const int MAXN=;
const int INF=<<;
int g[MAXN][MAXN],Mx[MAXN],My[MAXN],Nx,Ny;
int dx[MAXN],dy[MAXN],dis;
bool vst[MAXN];
struct Node1
{
int x,y,s;
}guests[MAXN];
struct Node2
{
int x,y;
}um[MAXN];
double distance(Node1 a,Node2 b)
{
double x=a.x-b.x;
double y=a.y-b.y; return sqrt(x*x+y*y);
}
bool searchP()
{
queue<int>Q;
dis=INF;
memset(dx,-,sizeof(dx));
memset(dy,-,sizeof(dy));
for(int i=;i<Nx;i++)
if(Mx[i]==-)
{
Q.push(i);
dx[i]=;
}
while(!Q.empty())
{
int u=Q.front();
Q.pop();
if(dx[u]>dis) break;
for(int v=;v<Ny;v++)
if(g[u][v]&&dy[v]==-)
{
dy[v]=dx[u]+;
if(My[v]==-) dis=dy[v];
else
{
dx[My[v]]=dy[v]+;
Q.push(My[v]);
}
}
}
return dis!=INF;
}
bool DFS(int u)
{
for(int v=;v<Ny;v++)
if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+)
{
vst[v]=;
if(My[v]!=-&&dy[v]==dis) continue;
if(My[v]==-||DFS(My[v]))
{
My[v]=u;
Mx[u]=v;
return ;
}
}
return ;
}
int MaxMatch()
{
int res=;
memset(Mx,-,sizeof(Mx));
memset(My,-,sizeof(My));
while(searchP())
{
memset(vst,,sizeof(vst));
for(int i=;i<Nx;i++)
if(Mx[i]==-&&DFS(i)) res++;
}
return res;
} int main(){
int n,m,t,i,j;
int T,iCase=;
scanf("%d",&T);
while(T--)
{
iCase++;
scanf("%d",&t);
scanf("%d",&m);
for(i=;i<m;i++)
scanf("%d%d%d",&guests[i].x,&guests[i].y,&guests[i].s);
scanf("%d",&n);
for(i=;i<n;i++)
scanf("%d%d",&um[i].x,&um[i].y);
Nx=m;Ny=n;
memset(g,,sizeof(g));
for(i=;i<m;i++)
{
for(j=;j<n;j++)
{
if(distance(guests[i],um[j])/guests[i].s-t<eps)
{
g[i][j]=;
}
}
}
printf("Scenario #%d:\n%d\n\n",iCase,MaxMatch());
}
return ;
}

二分图------》Hopcroft-Karp算法 hdu2389的更多相关文章

  1. hdu2389二分图之Hopcroft Karp算法

    You're giving a party in the garden of your villa by the sea. The party is a huge success, and every ...

  2. SPOJ 4206 Fast Maximum Matching (二分图最大匹配 Hopcroft-Carp 算法 模板)

    题目大意: 有n1头公牛和n2头母牛,给出公母之间的m对配对关系,求最大匹配数.数据范围:  1 <= n1, n2 <= 50000, m <= 150000 算法讨论: 第一反应 ...

  3. HDU 5943 Kingdom of Obsession 【二分图匹配 匈牙利算法】 (2016年中国大学生程序设计竞赛(杭州))

    Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  4. USACO 4.2 The Perfect Stall(二分图匹配匈牙利算法)

    The Perfect StallHal Burch Farmer John completed his new barn just last week, complete with all the ...

  5. (转)二分图匹配匈牙利算法与KM算法

    匈牙利算法转自于: https://blog.csdn.net/dark_scope/article/details/8880547 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名 ...

  6. HDU 2444 - The Accomodation of Students - [二分图判断][匈牙利算法模板]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2444 Time Limit: 5000/1000 MS (Java/Others) Mem ...

  7. 训练指南 UVALive - 4043(二分图匹配 + KM算法)

    layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true ...

  8. 最大流算法之Ford-Fulkerson算法与Edmonds–Karp算法

    引子 曾经很多次看过最大流的模板,基础概念什么的也看了很多遍.也曾经用过强者同学的板子,然而却一直不会网络流.虽然曾经尝试过写,然而即使最简单的一种算法也没有写成功过,然后对着强者大神的代码一点一点的 ...

  9. HDU2389 Rain on your Parade —— 二分图最大匹配 HK算法

    题目链接:https://vjudge.net/problem/HDU-2389 Rain on your Parade Time Limit: 6000/3000 MS (Java/Others)  ...

随机推荐

  1. Java 创建文件夹和文件

    String path="D://my"; File folder=new File(path); if(!folder.exists() && !folder.i ...

  2. JStorm集群的安装和使用

    0 JStorm概述 JStorm是一个分布式的实时计算引擎.从应用的角度,JStorm应用是一种遵守某种编程规范的分布式应用:从系统角度, JStorm是一套类似MapReduce的调度系统: 从数 ...

  3. Java中hashCode的作用

    转  http://blog.csdn.net/fenglibing/article/details/8905007 Java中hashCode的作用 2013-05-09 13:54 64351人阅 ...

  4. sqlserver权限体系(下)

    简介 在上一篇文章中,我对主体的概念做了全面的阐述.本篇文章接着讲述主体所作用的安全对象以及所对应的权限. 理解安全对象(Securable) 安全对象,是SQL Server 数据库引擎授权系统控制 ...

  5. nlssort函数的用法以及参数

    NLSSORT,可以用来进行语言排序,且不影响当前会话. 用法示例: 拼音SELECT * FROM TEAM ORDER BY NLSSORT(排序字段,'NLS_SORT = SCHINESE_P ...

  6. 【转载】 C中的access函数

    分类: C/C++ int   access(const   char   *filename,   int   amode); amode参数为0时表示检查文件的存在性,如果文件存在,返回0,不存在 ...

  7. PHP 5.5 新特性

    文章转自:http://wulijun.github.io/2013/07/17/whats-new-in-php-5-5.html http://www.cnblogs.com/yjf512/p/3 ...

  8. Myeclipse中的web项目审查(jquery-2.1.1.min.js)出现错误

    前言,本来在把web项目搞得好看一些,从网上下载了一个很炫酷的模板导入web中,无奈出现了错误,如下:

  9. Kali Linux中MySQL重置root密码

    参考:使用mysqladmin命令修改MySQL密码与忘记密码 前言:(在Windows的DOS命令行下和在kali Linux下修改方法是一样的)在kali Linux中默认安装了MySQL的最新版 ...

  10. [设计模式] javascript 之 享元模式;

    享元模式说明 定义:用于解决一个系统大量细粒度对象的共享问题: 关健词:分离跟共享: 说明: 享元模式分单纯(共享)享元模式,以及组合(不共享)享元模式,有共享跟不共享之分:单纯享元模式,只包含共享的 ...