二部图的最大匹配问题代码详解

在复杂网络中,二部图是被经常使用到的一种分析问题的方法,本文将笔者最近学习的二部图知识汇总整理一下,以供交流学习。

二部图的最大匹配有三种基本的算法:1)BFS;2)DFS;3)Hopcroft-Karp算法 

1)BFS;2)DFS;

#include 
#include 
#include
#define MAXN 10000
using namespace std;


int mk[MAXN];                          //mk[i]=0表示未访问过,为1表示访问过
int nx=MAXN, ny=MAXN;                  //X,Y集合中顶点的个数
int g[MAXN][MAXN];                     //邻接矩阵,g[i][j]为1,表示Xi,Yj有边相连
int cx[MAXN],cy[MAXN];                 //cx[i]最终求得的最大匹配中与Xi匹配的Y顶点,cy[i]同理
int pred[MAXN];                        //用来记录交错轨的,同时也用来记录Y集合中的顶点是否被遍历过
int queue[MAXN];                       //实现BFS搜索时,用到的队列(用数组模拟)


int read()                             //读取数据,数组存储
{
    ifstream cin("ER_data.txt",ios::in);
//ifstream cin("test.txt",ios::in);
    for(int i=0;i>x>>y)
        g[x][y]=1;
    cin.close();
    return 0;
}


int path (int u)
{
    for (int v=0; v -1)                //更改交错轨上的匹配状态
        {
            cx[ cy[pred[y]]]=y;
            cy[y]=cy[pred[y]];
            y=pred[y];
        }
        cy[y]=i; cx[i]=y; 
        res++;                            //匹配数加1
    }
    return res;
}


int main(){
    read();                               //读数据
    int max1,max2; 
    max1 = DMaxMatch();                   //DFS找的最大匹配
    max2 = BMaxMatch();                   //BFS找的最大匹配
    cout<

 

3)/*Hopcroft-Karp算法代码*/

#include 
#include 
#include 
#include 
#include 
using namespace std;


const int MAXN = 100 ;
const int INF = 1 << 28;
bool flag;
int p=MAXN,n=MAXN;
int Mx[MAXN], My[MAXN], Nx=MAXN, Ny=MAXN;
int dx[MAXN], dy[MAXN], dis;
bool vst[MAXN];
int g[MAXN][MAXN];


int read()
{
ifstream cin("ER_data-1.txt",ios::in);
    //ifstream cin("ER_data.txt",ios::in);
//ifstream cin("test.txt",ios::in);
    for(int i=0;i>x>>y)
        g[x][y]=1;
    cin.close();
    return 0;
}


bool BFS(void)                                   //BFS
{
    queue  Q;
    dis = INF;
    memset(dx, -1, sizeof(dx));
    memset(dy, -1, sizeof(dy));
    for (int i = 0; i < Nx; i++)
        if (Mx[i] == -1)
        {
            Q.push(i); dx[i] = 0;
        }
    while (!Q.empty())
    {
        int u = Q.front(); Q.pop();
        if (dx[u] > dis) break;                      //该增广路径长度大于dis还没有结束,等待下一次BFS再扩充  
        for (int v = 0; v < Ny; v++)
            if (g[u][v] && dy[v] == -1)              //v是未匹配点
            {
                dy[v] = dx[u]+1;
                if (My[v] == -1) dis = dy[v];        //得到本次BFS的最大遍历长度
                else
                {
                    dx[My[v]] = dy[v]+1;             //v是匹配点,继续延伸
                    Q.push(My[v]);
                }
            }
    }
    return dis != INF;
}


bool DFS(int u)                                           //DFS
{
    for (int v = 0; v < Ny; v++)
        if (!vst[v] && g[u][v] && dy[v] == dx[u]+1)
        {
            vst[v] = 1;
            if (My[v] != -1 && dy[v] == dis) continue;    //增广路径的长度大于本次查找的dis,是BFS被break的情况,也就是还不确定是否是增广路径,只有等再次调用BFS再判断
            if (My[v] == -1 || DFS(My[v]))                //是增广路径,更新匹配集
            {
                My[v] = u; Mx[u] = v;
                return 1;
            }
        }
    return 0;
}


int MaxMatch()
{
    int res = 0;
    memset(Mx, -1, sizeof(Mx));
    memset(My, -1, sizeof(My));
    while (BFS()) 
{
        memset(vst, 0, sizeof(vst));
        for (int i = 0; i < Nx; i++)
            if (Mx[i] == -1 && DFS(i)) 
res++;                                   //查找到一个增广路径,匹配数增加
    }  
    return res;  
}


int main() 
{
    read();
    int max = MaxMatch();
    cout<

Research Paper and Reference:https://github.com/Shuanbao-Liu/Controllability-on-CompleX-Network

你可能感兴趣的:(科研经验,复杂网络)