Machine Schedule HDU - 1150 最小点覆盖

//匈牙利求最大匹配
//从左边每个非匹配点出发,做一遍增广,标记所有经过的点,
//左边所有未被标记的点,和右边所有被标记的点,加起来就是要构造的方案
//左边所有的非匹配点,都被标记了,
//右边所有的非匹配点,一定没有被标记
//对于每一个匹配边,左右两点要么同时被标记,要么同时不被标记
//那么左边剩下的未被标记的点,一定是匹配点
//右边所有被标记的点,都是匹配点

//不在匹配中的情况:左边的非匹配点连向右边的匹配点(被标记) 
//					左边的匹配点(不被标记)连向右边的非匹配点
//

//最小点覆盖==最大匹配数 
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
int n, m, k;
int match[N];
bool g[N][N], st[N];
bool find(int x)
{
    for (int i = 0; i < m; i ++ )
        if (!st[i] && g[x][i])
        {
            st[i] = true;
            if (match[i] == -1 || find(match[i]))
            {
                match[i] = x;
                return true;
            }
        }

    return false;
}
int main()
{
    while (cin >> n, n)
    {
        cin >> m >> k;
        //图 
        memset(g, 0, sizeof g); 
        memset(match, -1, sizeof match);
        while (k -- )
        {
            int t, a, b;
            cin >> t >> a >> b;
            if (!a || !b) 
				continue;
            g[a][b] = true;
        }
        int res = 0;
        //求最大匹配数量==最少点覆盖 
        for (int i = 0; i < n; i ++ )
        {
            memset(st, 0, sizeof st);
            if (find(i)) 
				res ++ ;
        }
        cout << res << endl;
    }
    return 0;
}


posted @ 2020-03-02 22:29  晴屿  阅读(65)  评论(0)    收藏  举报