暂时只包括与最大匹配相关的问题。

求最大独立集,最小路径覆盖等等大多数题目都可以转化为求最大匹配用匈牙利算法解决。

1.最大匹配(边集)

此类问题最直接,直接用匈牙利算法即可。

HDU 2063  过山车

http://acm.hdu.edu.cn/showproblem.php?pid=2063

二分图最大匹配模版题。

ZOJ 1654 - Place the Robots

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1654

易想到求最大独立集但是时间复杂度太高,可以变成二分图最大匹配来做,重在建模。

2.最小路径覆盖(边集)

对于不存在孤立的点的图,|最小路径覆盖|+|最大匹配|=V(顶点数)

因此可以通过求最大匹配来做。

这个等式在DAG图中也成立,详见http://www.cnblogs.com/jackiesteed/articles/2043934.html。对于DAG图可以拆点来做。

HDU 1151 Air Raid

http://acm.hdu.edu.cn/showproblem.php?pid=1151

 #include<iostream>
 #include<cstring>
 #include<cmath>
 #include<algorithm>
 #include<cstdlib>
 #include<cstdio>
 #include<vector>
 #define MAXN 1005
 using namespace std;
 bool gl[MAXN][MAXN];
 int link[MAXN];
 int n;
 bool vis[MAXN];

 bool match(int x)
 {
     ; i<=n; ++i)
         if(gl[x][i]&&!vis[i])
         {
             vis[i]=true;
             ||match(link[i]))
             {
                 link[i]=x;
                 return true;
             }
         }
     return false;
 }
 int main()
 {
     int T;
     scanf("%d",&T);
     while(T--)
     {  int m;
         scanf("%d%d",&n,&m);
         memset(gl,,sizeof(gl));
         ;i<m;++i)
         {
             int x,y;
             scanf("%d%d",&x,&y);
             gl[x][y]=true;
         }
         ;
         memset(link,-,sizeof(link));
         ; i<=n; ++i)
         {
             memset(vis,,sizeof(vis));
             if(match(i)) res++;
         }
         printf("%d\n",n-res);
     }
     ;
 }

求DAG的最小路径覆盖。

3.最小顶点覆盖(点集)

在二分图中|最大匹配|=|最小顶点覆盖|,但是注意要解决的问题本身并不是最大匹配,理解了问题本身才能建模。

HDU 1054  Strategic Game

http://acm.hdu.edu.cn/showproblem.php?pid=1054

此题可以用树形DP来做也可以用求最小顶点覆盖,但是时间较慢。拆点,改成双向图,用邻接表。

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<vector>
#define MAXN 1505
using namespace std;
vector<int> gl[MAXN];
int link[MAXN];
int n;
bool vis[MAXN];
void init()
{
    memset(link,-,sizeof(link));
    memset(vis,,sizeof(vis));
}

bool match(int x)
{
    ; i<gl[x].size(); ++i)
    {
        int &u=gl[x][i];
        if(!vis[u])
        {
            vis[u]=true;
            ||match(link[u]))
            {
                link[u]=x;
                return true;
            }
        }
    }

    return false;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(gl,,sizeof(gl));
        ; i<n; ++i)  gl[i].clear();
        ; i<n; ++i)
        {
            int now,t,cn;
            scanf("%d:",&now);
            scanf("(%d)",&cn);
            while(cn--)
            {
                scanf("%d",&t);
                gl[now].push_back(t);
                gl[t].push_back(now);
            }
        }
        init();
        ;
        ; i<n; ++i)
        {
            memset(vis,,sizeof(vis));
            if(match(i)) res++;
        }
        printf();
    }
    ;
}

HDU 1150  Machine Schedule

http://acm.hdu.edu.cn/showproblem.php?pid=1150

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<vector>
#define MAXN 1005
using namespace std;
bool gl[MAXN][MAXN];
int link[MAXN];
int n,m;
bool vis[MAXN];

bool match(int x)
{
    ; i<=m; ++i)
        if(gl[x][i]&&!vis[i])
        {
            vis[i]=true;
            ||match(link[i]))
            {
                link[i]=x;
                return true;
            }
        }
    return false;
}
int main()
{
    int t;
    while(scanf("%d",&n)&&n)
    {
        scanf("%d%d",&m,&t);
        memset(gl,,sizeof(gl));
        ; i<t; ++i)
        {
            int x,y,z;
            scanf("%d%d%d",&z,&x,&y);
            gl[x][y]=true;
        }
        ;
        memset(link,-,sizeof(link));
        ; i<=n; ++i)
        {
            memset(vis,,sizeof(vis));
            if(match(i)) res++;
        }
        printf("%d\n",res);
    }
    ;
}

4.最大独立集(点集)

|最大独立集|+|最小顶点覆盖|=V

求最大独立集是NP问题,但是在二分图中|最大匹配|=|最小顶点覆盖|,所以这个问题也有了高效的算法。

HDU 1045  Fire Net

http://acm.hdu.edu.cn/showproblem.php?pid=1045

这个可以暴力求最大独立集。

HDU 2768  Cat vs. Dog

http://acm.hdu.edu.cn/showproblem.php?pid=2768

根据矛盾之间建图,求最大独立集。

HDU 1068  Girls and Boys

http://acm.hdu.edu.cn/showproblem.php?pid=1068

题意很明显就是求二分图最大独立集。但是由于没说给的是男还是女,所以需要拆点,得到的最大匹配数要除以2,再套用公式得最大独立集。

 #include<iostream>
 #include<cstring>
 #include<cmath>
 #include<algorithm>
 #include<cstdlib>
 #include<cstdio>
 #include<vector>
 #define MAXN 1005
 using namespace std;
 bool gl[MAXN][MAXN];
 int link[MAXN];
 int n;
 bool vis[MAXN];
 void init()
 {
     memset(link,-,sizeof(link));
     memset(vis,,sizeof(vis));
 }

 bool match(int x)
 {
     ; i<n; ++i)
         if(gl[x][i]&&!vis[i])
         {
             vis[i]=true;
             ||match(link[i]))
             {
                 link[i]=x;
                 return true;
             }
         }
     return false;
 }
 int main()
 {
     while(scanf("%d",&n)!=EOF)
     {
         memset(gl,,sizeof(gl));
         ; i<n; ++i)
         {
             int now,t,cn;
             scanf("%d: ",&now);
             scanf("(%d) ",&cn);
             while(cn--)
             {
                 scanf("%d",&t);
                 gl[now][t]=true;
             }
         }
         init();
         ;
         ; i<n; ++i)
         {
             memset(vis,,sizeof(vis));
             if(match(i)) res++;
         }
         printf(-res)/);
     }
     ;
 }

5.判断二分图

此类问题可以BFS或DFS解决,注意图可能不连通。

HDU 4751 Divide Groups

http://acm.hdu.edu.cn/showproblem.php?pid=4751

根据不互相认识这一关系连边,判断二分图。

ACM -二分图题目小结的更多相关文章

  1. ACM - KMP题目小结 (更新中)

    KMP算法题型大致有两类,一类是next数组的应用,一类是匹配问题. next数组大多数是求字符串周期,或者是与前缀后缀有关,也可以应用在DP中.需要对next数组有一定理解才能做得出. next数组 ...

  2. ACM - 概率、期望题目 小结(临时)

    概率DP求期望大多数都是全期望公式的运用.主要思考状态空间的划分以及状态事件发生的概率.问题可以分为无环和有环两类.无环一类多数比较简单,可以通过迭代或者记忆化搜索完成.有环一类略复杂,可以通过假设方 ...

  3. 【Mark】博弈类题目小结(HDU,POJ,ZOJ)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 首先当然要献上一些非常好的学习资料: 基础博弈的小 ...

  4. ACM计算几何题目推荐

    //第一期 计算几何题的特点与做题要领: 1.大部分不会很难,少部分题目思路很巧妙 2.做计算几何题目,模板很重要,模板必须高度可靠. 3.要注意代码的组织,因为计算几何的题目很容易上两百行代码,里面 ...

  5. ACM一些题目

    Low Power 先二分答案,可以通过调整证明同一台机器选的两个芯片必然是提供能量数值相邻的两个.所以再贪心一下就可以了. 时间复杂度\(O(n \log n)\). Factors 假设\(k\) ...

  6. CDQ分治题目小结

    CDQ分治属于比较特殊的一类分治,许多问题转化为这类分治的时候,时空方面都会有很大节省,而且写起来没有这么麻烦. 这类分治的特殊性在于分治的左右两部分的合并,作用两部分在合并的时候作用是不同的,比如, ...

  7. 2015暑假acm短训小结

    时间很快,短训已经结束,短短20天,心里有一些思绪想要记下. 收获: 从最近发的随笔中可以看出,做得最多的是搜索——Dfs,Bfs.对于搜索,如何描述状态,如何压缩状态,如何决定下一个结点,是否可以剪 ...

  8. codeforeces近日题目小结

    题目源自codeforeces的三场contest contest/1043+1055+1076 目前都是solved 6/7,都差了最后一题 简单题: contest/1043/E: 先不考虑m个限 ...

  9. ACM 字符串 题目整理

    AC自动机 UVa 11468  Substring AC自动机+概率DP. 注意要补全不存在的边. 为什么要补全不存在的边呢?补全以后可以直接找到状态的转移,即从所有子节点就可以实现所有状态转移. ...

随机推荐

  1. 解决PhoneGap不支持viewport的几种方法

    前几天用phonegap编译GameBuilder+CanTK时,发现HTML里的viewport无效.CanTK根据devicePixelRatio检测设备的DPI,然后用viewport设置正确的 ...

  2. .NET Reflector 8.2支持VS2013高亮显示和代码地图视图

    Red Gate Software公司最近发布的.NET Reflector 8.2支持Visual Studio 2013,其Reflector 桌面程序能够转换十六进制/十进制值.桌面程序还支持局 ...

  3. CSDN中的Bug

    简述 在用CSDN的过程中,发现了许许多多的Bug.之前没有做记录,直接反馈给客服了,有时没图说得不太清楚,现在不都追求有图有真相么O(∩_∩)O~,所以在此记录一下. 作为程序员的一份子,Bug对我 ...

  4. MySQL学习笔记_1_MySQL数据库管理系统概述

    1. MySQL架构 C/S: client / server架构 MySQL DBMS(Data Bank Management System): 数据库管理系统 客户端 <---> 服 ...

  5. 笔记11:GDI 制作数字验证码

    大二学长让我学下GDI绘制验证码,然后自己就试了试了.找了点视频看了下. 现在会画直线,矩形,字符串,制作验证码 一.绘制一条直线 private void button1_Click(object ...

  6. Junit4入门

    eclipse自带junit包,可右键直接新建junit类 静态引入:import static org.junit.Assert.* assert.*是类,静态引入会引入assert里的所有静态方法 ...

  7. C++ 如何重复利用一个内存地址块

    #include<iostream> using namespace std; ; }; int main(int argv ,char * args[]) { double *p1,*p ...

  8. 使用git上传项目

    1. 安装Git 2. 安装TortoiseGit 3.任意文件夹选择「TortoiseGit」>「settings」,打开如下界面. 3. 生成SSH公钥 3.1运行Git Bash,如下命令 ...

  9. Problem 2020 组合(FOJ)

    Problem 2020 组合 Accept: 714    Submit: 1724Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem ...

  10. DOM系列---进阶篇【转】

    内容提纲: 1.DOM类型 2.DOM扩展 3.DOM操作内容 一.DOM类型 DOM基础篇中,我们了解了DOM的节点并且了解怎样查询和操作节点,而本身这些不同的节点,又有着不同的类型.   DOM类 ...