hdu1150-Machine Schedule(最小点覆盖)

二分图的最小顶点覆盖:用最少的点,让每条边都至少和其中一个点关联。
     最大匹配数 = 最小点覆盖数(Konig 定理)

水题……

突然发现我以前的匈牙利算法模版有问题……因为这里左边的点时1~n,右边的点是1~m,所以有不同的点标号是相同的,注意注意!

因为这个算法本身是O(n^2)的,所以数据必然不会很大,放心用邻接矩阵存吧……

如果某个边有0,那么不需要加进来,每个产品应该只会出现一次,不然就不对了吧……我想了好久,因为题目并没有说每个产品只出现一次……

//hdu1150
#include <cstdio>  
#include <cstring>  
#include <iostream>  
using namespace std;
const int N = 105;
int n, m, k;
bool mp[N][N];

int match[N];
bool used[N];

bool find(int u) {
    for (int v = 0; v < m; ++v) {
        if (mp[u][v] && !used[v]) {
            used[v] = true;
            if (match[v] == -1 || find(match[v])) {
                match[v] = u;
                return true;
            }
        }
    }
    return false;
}

int hungary() {
    memset(match, -1, sizeof match);
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        memset(used, false, sizeof used);
        if (find(i)) ++ans;
    }
    return ans;
}

int main() {
    //freopen("in", "r", stdin);
    while (~scanf("%d", &n) && n) {
        scanf("%d%d", &m, &k);
        int u, v;
        memset(mp, false, sizeof mp);
        while (k--) {
            scanf("%*d%d%d", &u, &v);
            if (!u || !v) continue;
            mp[u][v] = true;
        }
        printf("%d\n", hungary());
    }
    return 0;
}

 

  

posted @ 2016-08-23 14:22  我不吃饼干呀  阅读(688)  评论(0编辑  收藏  举报