• HDU


    二分图匹配的模板

     

    二分图:如果顶点集 V可分割为两个互不相交的子集X和Y,并且图中每条边连接的两个顶点一个在 X中,另一个在 Y中,则称图G为二分图。

    交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路

    增广路:两个端点都是未盖点的交替路叫做可增广路。

     

    伪代码:

    bool(u)

    {

      for(u所连的点)

      {

        if  v不在交替路上

        {

          将v加入交替路

          if v点未匹配||有可能有增长路

          {

            标记;

            ture;

          }

        }

      }

      false;

    }

     

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<stack>
     6 #include<queue>
     7 #include<cmath>
     8 #include<set>
     9 
    10 
    11 #define ll long long
    12 #define mem(a,b) memset(a,b,sizeof(a))
    13 #define inf 0x3f3f3f3f
    14 
    15 using namespace std;
    16 
    17 const int maxn=3e4+10;
    18 
    19 struct edge{
    20     int u,v,next;
    21 }e[maxn*2];
    22 
    23 int g[maxn*2],vis[maxn*2],dis[maxn*2],cheek[maxn];
    24 int tot;
    25 
    26 void init()
    27 {
    28     mem(g,0);
    29     mem(vis,0);
    30     mem(e,0);
    31     mem(dis,0);
    32     tot=0;
    33 }
    34 
    35 void make_edge(int u,int v)
    36 {
    37     e[++tot]=(edge){u,v,g[u]};
    38     g[u]=tot;
    39 }
    40 
    41 bool dfs(int u)
    42 {
    43     for(int i=g[u];i>0;i=e[i].next)
    44     {
    45         int v=e[i].v;
    46         if(!cheek[v])//如果v不在交替路上
    47         {
    48             cheek[v]=1;//将v加入交替路
    49             if(!vis[v]||dfs(vis[v]))//如果v点未被覆||有可能有增广路 标记
    50             {
    51                 //vis[u]=v;
    52                 vis[v]=u;
    53                 return true;//如果有增广路
    54             }
    55         }
    56     }
    57     return false;//
    58 }
    59 
    60 int hungarian(int n,int m)
    61 {
    62     int ans=0;
    63     for(int u=m+1;u<=n+m;u++)//枚举一个集合的点
    64     {
    65         if(vis[u]==0)//未被覆盖
    66         {
    67             mem(cheek,0);
    68             if(dfs(u))  ans++;//匹配++;
    69         }
    70     }
    71     return ans;
    72 }
    73 
    74 int main(){
    75     int t;
    76     scanf("%d",&t);
    77     while(t--)
    78     {
    79         init();
    80         int n,m;
    81         scanf("%d%d",&n,&m);
    82         for(int i=1;i<=n;i++)
    83         {
    84             int t;
    85             scanf("%d",&t);
    86             for(int j=1;j<=t;j++)
    87             {
    88                 int now;
    89                 scanf("%d",&now);
    90                 make_edge(m+i,now);
    91                 //make_edge(now,m+i);
    92             }
    93         }
    94         int temp=hungarian(n,m);
    95         //cout<<temp<<endl;
    96         cout<<(temp==n?"YES":"NO")<<endl;
    97     }
    98     return 0;
    99 }

     

  • 相关阅读:
    phpStrom添加插件:php文档生成(phpDocumentor)
    apache2.2 虚拟主机配置
    PHP环境(apache,PHP,Mysql)详细配置方法
    PHP设计模式之工厂模式(权限分配)
    PHP的接口类(interface)和抽象类(abstract)的区别
    PHP设计模式之单例模式(数据库访问)
    windows svn 客户端连不上linux svn server
    Xshell6和Xftp下载地址,rzsz的使用
    linux文件删除,剩余空间没变化
    thinkphp的_STORAGE_WRITE_ERROR_问题
  • 原文地址:https://www.cnblogs.com/minun/p/10498469.html
Copyright © 2020-2023  润新知