算法导论—二分图

来源:互联网 发布:手机蓝牙软件 编辑:程序博客网 时间:2024/06/10 00:05

华电北风吹
天津大学认知计算与应用重点实验室
日期:2015/9/13

一、二分图定义
简单来说,如果图中顶点可以分为两组,使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交集 U 和V ,使得每一条边都分别连接U、V中的顶点。如果存在这样的划分,则此图为一个二分图。二分图的一个等价定义是:不含有含奇数条边的环的图。
二、二分图的判断
染色法+广度优先搜索

function result=BipartiteGraph(connectGraph)% connectGraph 联通图[m n]=size(connectGraph);nodelist=zeros(m,1);nodecolor=-ones(m,1);startNode=1;queue=startNode;nodelist(startNode)=1;nodecolor(startNode)=1;while isempty(queue)==false    i=queue(1);    queue(1)=[];    for j=1:n        if(connectGraph(i,j)>0&&i~=j)            if(nodelist(j)==0)                queue=[queue;j];                nodelist(j)=1;                nodecolor(j)=1-nodecolor(i);            else                if nodecolor(j)==nodecolor(i)                    result=0;                    return;                end            end        end    endendresult=1;

三、二分图的最大匹配
匹配:在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点。例如,图 3、图 4 中红色的边就是图 2 的匹配。
最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。图 4 是一个最大匹配,它包含 4 条匹配边。
完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。图 4 是一个完美匹配。显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。但并非每个图都存在完美匹配。

#include<stdio.h>#include<string.h>#include <iostream>#include <fstream>using namespace std;#define SIZE 10int choice[SIZE][SIZE];int visited[SIZE], link[SIZE];int M, N;int find(int pos){    int i;    for (i = 1; i <= N; i++)    {        if (visited[i] == 0 && choice[pos][i] == 1)        {            visited[i] = 1;            if (link[i] == 0 || find(link[i]))            {                link[i] = pos;                return 1;            }        }    }    return 0;}int main(){    ifstream in(".\\input.txt");    cin.rdbuf(in.rdbuf());    int K, i, a, b, ans;    while (cin>>K && K)    {        memset(choice, 0, sizeof(choice));        memset(link, 0, sizeof(link));        cin >> M >> N;        while (K--)        {            cin >> a >> b;            choice[a][b] = 1;        }        ans = 0;        for (i = 1; i <= M; i++)        {            memset(visited, 0, sizeof(visited));            if (find(i))                ans++;        }        cout << ans << endl;    }    system("pause");    return 0;}

参考博客:
http://www.renfei.org/blog/bipartite-matching.html

0 0
原创粉丝点击