二分匹配的Hopcroft-Carp算法

本文介绍了二分匹配中Hopcroft-Carp算法的实现细节及其优势。通过对比匈牙利算法,该算法在时间复杂度上更优,适用于处理大规模数据集。文中还提供了具体的C++实现代码。
 

二分匹配的Hopcroft-Carp算法

分类: 图论   96人阅读  评论(0)  收藏  举报

题目:HDU2063 过山车

 

果然Hopcroft-Carp算法快,用匈牙利算法15ms,而Hopcorft-Carp却0ms。因为匈牙利算法的时间复杂度为O(n*e),而Hopcroft-Carp算法O(sqrt(n)*e)

本算法适合处理大一点的数据。。。。。。

 

[cpp]  view plain copy
  1. #include <stdio.h>  
  2. #include <iostream>  
  3. #include <string.h>  
  4. #include <queue>  
  5.   
  6. const int N=1005;  
  7. const int INF=1<<28;  
  8.   
  9. int g[N][N];  
  10. int Mx[N];  
  11. int My[N];  
  12. int dx[N];  
  13. int dy[N];  
  14. bool used[N];  
  15.   
  16. int Nx,Ny,dis;  
  17.   
  18. bool searchP()  
  19. {  
  20.     dis=INF;  
  21.     int i,v,u;  
  22.     std::queue<int> Q;  
  23.   
  24.     memset(dx,-1,sizeof(dx));  
  25.     memset(dy,-1,sizeof(dy));  
  26.     for(i=0;i<Nx;i++)  
  27.     {  
  28.         if(Mx[i]==-1)  
  29.         {  
  30.             Q.push(i);  
  31.             dx[i]=0;  
  32.         }  
  33.     }  
  34.     while(!Q.empty())  
  35.     {  
  36.         u=Q.front();  
  37.         Q.pop();  
  38.         if(dx[u]>dis) break;  
  39.         for(v=0;v<Ny;v++)  
  40.         {  
  41.             if(g[u][v]&&dy[v]==-1)  
  42.             {  
  43.                 dy[v]=dx[u]+1;  
  44.                 if(My[v]==-1) dis=dy[v];  
  45.                 else  
  46.                 {  
  47.                     dx[My[v]]=dy[v]+1;  
  48.                     Q.push(My[v]);  
  49.                 }  
  50.             }  
  51.         }  
  52.     }  
  53.     return dis!=INF;  
  54. }  
  55.   
  56. bool DFS(int u)  
  57. {  
  58.     int v;  
  59.     for(v=0;v<Ny;v++)  
  60.     {  
  61.         if(g[u][v]&&!used[v]&&dy[v]==dx[u]+1)  
  62.         {  
  63.             used[v]=true;  
  64.             if(My[v]!=-1&&dy[v]==dis) continue;  
  65.             if(My[v]==-1||DFS(My[v]))  
  66.             {  
  67.                 My[v]=u;  
  68.                 Mx[u]=v;  
  69.                 return true;  
  70.             }  
  71.         }  
  72.     }  
  73.     return false;  
  74. }  
  75.   
  76. int Hungary()  
  77. {  
  78.     int u;  
  79.     int ret=0;  
  80.     memset(Mx,-1,sizeof(Mx));  
  81.     memset(My,-1,sizeof(My));  
  82.     while(searchP())  
  83.     {  
  84.         memset(used,false,sizeof(used));  
  85.         for(u=0;u<Nx;u++)  
  86.            if(Mx[u]==-1&&DFS(u))  ret++;  
  87.     }  
  88.     return ret;  
  89. }  
  90.   
  91. int main()  
  92. {  
  93.     int k,u,v;  
  94.     while(~scanf("%d",&k),k)  
  95.     {  
  96.         scanf("%d%d",&Nx,&Ny);  
  97.         memset(g,0,sizeof(g));  
  98.         Ny=Nx>Ny? Nx:Ny;  
  99.         while(k--)  
  100.         {  
  101.             scanf("%d%d",&u,&v);  
  102.             u--;v--;  
  103.             g[u][v]=1;  
  104.         }  
  105.         int ans=Hungary();  
  106.         printf("%d\n",ans);  
  107.     }  
  108.     return 0;  
  109. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值