1. 程式人生 > >POJ 1325 Machine Schedule (二分圖最小點集覆蓋 匈牙利演算法)

POJ 1325 Machine Schedule (二分圖最小點集覆蓋 匈牙利演算法)

Machine Schedule
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 12621 Accepted: 5399

Description

As we all know, machine scheduling is a very classical problem in computer science and has been studied for a very long history. Scheduling problems differ widely in the nature of the constraints that must be satisfied and the type of schedule desired. Here we consider a 2-machine scheduling problem.

There are two machines A and B. Machine A has n kinds of working modes, which is called mode_0, mode_1, ..., mode_n-1, likewise machine B has m kinds of working modes, mode_0, mode_1, ... , mode_m-1. At the beginning they are both work at mode_0.

For k jobs given, each of them can be processed in either one of the two machines in particular mode. For example, job 0 can either be processed in machine A at mode_3 or in machine B at mode_4, job 1 can either be processed in machine A at mode_2 or in machine B at mode_4, and so on. Thus, for job i, the constraint can be represent as a triple (i, x, y), which means it can be processed either in machine A at mode_x, or in machine B at mode_y.

Obviously, to accomplish all the jobs, we need to change the machine's working mode from time to time, but unfortunately, the machine's working mode can only be changed by restarting it manually. By changing the sequence of the jobs and assigning each job to a suitable machine, please write a program to minimize the times of restarting machines.

Input

The input file for this program consists of several configurations. The first line of one configuration contains three positive integers: n, m (n, m < 100) and k (k < 1000). The following k lines give the constrains of the k jobs, each line is a triple: i, x, y.

The input will be terminated by a line containing a single zero.

Output

The output should be one integer per line, which means the minimal times of restarting machine.

Sample Input

5 5 10
0 1 1
1 1 2
2 1 3
3 1 4
4 2 1
5 2 2
6 2 3
7 2 4
8 3 3
9 4 3
0

Sample Output

3

Source

Beijing 2002

題目連結:http://poj.org/problem?id=1325

題目大意:兩個機器,每個作業可以在不同機器的不同模式下工作,A x y表示作業A可以由機器1的x模式或者機器2的y模式完成,要完成所有作業,必須不斷切換機器模式,試尋找適合的分配關係使得切換次數最小,注意機器1和機器2開始都工作在0模式,求最小次數

題目分析:二分圖最小點集覆蓋問題,1和2兩個機器作為二分圖的兩邊,按每個工作對應的1,2機器模式建邊,然後就是求這個二分圖的最小點覆蓋,即最小的點集,使得其包含所有的邊,根據二分圖的最小點集覆蓋數=最大匹配,所以直接用匈牙利演算法求解最大匹配即可,注意0模式時不要連邊即可

#include <cstdio>
#include <cstring>
int const MAX = 105;
bool g[MAX][MAX];
int cx[MAX], cy[MAX];
bool vis[MAX];
int n, m, k;

int DFS(int x)
{
    for(int y = 0; y < m; y++)
    {
        if(!vis[y] && g[x][y])
        {
            vis[y] = true;
            if(cy[y] == -1 || DFS(cy[y]))
            {
                cx[x] = y;
                cy[y] = x;
                return 1;
            }
        }
    }
    return 0;
}

int MaxMatch()
{
    int res = 0;
    memset(cx, -1, sizeof(cx));
    memset(cy, -1, sizeof(cy));
    for(int i = 0; i < n; i++)
    {
        if(cx[i] == -1)
        {
            memset(vis, false, sizeof(vis));
            res += DFS(i);
        }
    }
    return res;
}

int main()
{
    while(scanf("%d", &n) != EOF && n)
    {
        memset(g, false, sizeof(g));
        scanf("%d %d", &m, &k);
        for(int i = 0; i < k; i++)
        {
            int tmp, x, y;
            scanf("%d %d %d", &tmp, &x, &y);
            if(x * y)
                g[x][y] = true;
        }
        int ans = MaxMatch();
        printf("%d\n", ans);
    }
}