zoukankan      html  css  js  c++  java
  • 图论:匈牙利算法

    其实在写这个的代码的时候我是纳闷的,X集合和Y集合的点,能同时用1,或者2来表示吗?

    然后我努力说服自己:它已经是二分图了

    它就是存了一个 → 而已

    好的我被自己说服了

    二分图匹配说的就是,每个人有若干种选择,但是每种选择只能容纳一个人,问你最多能配对多少

    或者说成选边的时候不能经过同一个点

    最大匹配就是最多选择多少条边的问题

    匈牙利算法就是,有机会就上,没机会要创造机会也要上,尽可能地给当前腾地方,腾的过程是一个递归的过程

    其实这个算法挺矫情的。。

    bool find(int u)
    {
        for(int tmp=g[u];tmp;tmp=e[tmp].next)
            if(!y[e[tmp].t])
            {
                y[e[tmp].t]=1;
                if(lk[e[tmp].t]==0||find(lk[e[tmp].t]))
                {
                    lk[e[tmp].t]=u;
                    return 1;
                }
            }
            return 0;
    }

    建图之后,对于每个X中的点,清空y数组之后find就好了

    然后忘了说定义了,补上。。

    int n,m,cnt,ans;
    int y[maxn],lk[maxn],g[maxn];

    y记录的是Y中的下标节点是否被访问过

    lk记录的是与当前下标节点(Y中)相连的X中的节点

    然后给出完整实现:

     1 #include<cstdio>
     2 #include<cstring>
     3 const int maxn=205;
     4 const int maxm=205;
     5 int n,m,cnt,ans;
     6 int y[maxn],lk[maxn],g[maxn];
     7 struct Edge{int t,next;}e[maxn*maxm];
     8 void addedge(int u,int v)
     9 {
    10     e[++cnt].t=v;e[cnt].next=g[u];
    11     g[u]=cnt;
    12 }
    13 bool find(int u)
    14 {
    15     for(int tmp=g[u];tmp;tmp=e[tmp].next)
    16         if(!y[e[tmp].t])
    17         {
    18             y[e[tmp].t]=1;
    19             if(lk[e[tmp].t]==0||find(lk[e[tmp].t]))
    20             {
    21                 lk[e[tmp].t]=u;
    22                 return 1;
    23             }
    24         }
    25         return 0;
    26 }
    27 int main()
    28 {
    29     scanf("%d%d",&n,&m);
    30     int tmp,tmp1;
    31     for(int i=1;i<=n;i++)
    32     {
    33         scanf("%d",&tmp);
    34         for(int j=1;j<=tmp;j++)
    35         {
    36             scanf("%d",&tmp1);
    37             addedge(i,tmp1);
    38         }
    39     }
    40     for(int i=1;i<=n;i++)
    41     {
    42         memset(y,0,sizeof(y));
    43         if(find(i)) ans++;
    44     }
    45     printf("%d",ans);
    46     return 0;
    47 }

    老实说,这个算法,真的很神奇。。

  • 相关阅读:
    Linux下几种文件传输命令 sz rz sftp scp
    jqGrid subGrid配置 如何首次加载动态展开所有的子表格
    MySQL使用规范
    Navicat连接MySQL报错2059
    微信小程序
    完美解决 ios10 及以上 Safari 无法禁止缩放的问题
    html5利用getObjectURL获取图片路径上传图片
    Vue的单页应用中如何引用单独的样式文件
    用JS添加和删除class类名
    APP中的 H5和原生页面如何分辨、何时使用
  • 原文地址:https://www.cnblogs.com/aininot260/p/9434172.html
Copyright © 2011-2022 走看看