码迷,mamicode.com
首页 > 编程语言 > 详细

匈牙利算法模板

时间:2016-04-16 12:13:26      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:

邻接矩阵:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;

int mp[2100][2100]; // 图的存储矩阵
int n, m;
int ans;
bool vis[2100]; // 当前搜索过程中是否被访问过
int link[2100]; // y集合中的点在x集合中的匹配点 -1表示未匹配

bool find_(int x) {
    for (int i=1; i<=n; ++i) {
        if (mp[x][i] && !vis[i]) { // 有边相连
            vis[i] = 1; // 标记该点
            if (link[i] == -1 || find_(link[i])) { //该点未匹配 或者匹配的点能找到增光路
                link[i] = x; // 删掉偶数条边 加进奇数条边
                return true; // 找到增光路
            }
        }
    }
    return false;
}

void match() {
    //初始化
    ans = 0;
    memset(link, -1, sizeof(link));

    for (int i=1; i<=n; ++i) {
        memset(vis, 0, sizeof(vis)); // 从集合的每个点依次搜索
        if (find_(i)) // 如果能搜索到 匹配数加1
            ans++;
    }
    return;
}

int main() {
    while(cin >> n >> m) {
        memset(mp, 0, sizeof(mp));

        for (int i=0; i<m; ++i) {
            int x, y;
            cin >> x >> y;
            mp[x][y] = 1;
            mp[y][x] = 1;
        }

        //判断是不是二分图 过

        match();
        cout << ans/2 << endl;
    }
    return 0;
}

邻接表:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#define maxn 205
using namespace std;

int n, m;
int ans;
bool vis[maxn]; // 当前搜索过程中是否被访问过
int link[maxn]; // y集合中的点在x集合中的匹配点 -1表示未匹配

int head[maxn];
int tot;

struct Node {
    int v, nxt;
}edge[maxn*maxn];

void addEdge(int u, int v) {
    edge[tot].v = v;
    edge[tot].nxt = head[u];
    head[u] = tot++;
}

bool find_(int x) {
    for (int i=head[x]; i!=-1; i=edge[i].nxt) { // 遍历以x为顶点的所有边
        int v = edge[i].v;
        if (vis[v]) continue; // 如果v在当前寻找增光路过程中被访问过
        vis[v] = 1; // 标记访问
        if (link[v] == -1 || find_(link[v])) { // 如果v点没有被匹配过 或者 匹配点能找到增光路
            link[v] = x; // 增广路奇偶倒置
            return true;
        }
    }
    return false;
}

void match() {
    ans = 0;
    memset(link, -1, sizeof(link));

    for (int i=1; i<=n; ++i) {
        memset(vis, 0, sizeof(vis)); // 从集合的每个点依次搜索
        if (find_(i)) // 如果能搜索到 匹配数加1
            ans++;
    }
    return;
}


int main() {
    while(cin >> n >> m) {
        tot = 0;
        memset(head, -1, sizeof(head));
        for (int i=0; i<m; ++i) {
            int x, y;
            cin >> x >> y;
            addEdge(x, y);
            addEdge(y, x);
        }

        match();
        cout << ans/2 << endl;
    }
    return 0;
}

  

匈牙利算法模板

标签:

原文地址:http://www.cnblogs.com/icode-girl/p/5398049.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!