poj_Machine Schedule(匈牙利算法初步)

题意:就不多说了。

分析:(转的有图有真相吗)这个题目如果知道使用二分图的话就很简单了,关键就是如何构图。
poj_Machine Schedule(匈牙利算法初步)_第1张图片
依照题目意思能够构造出图(1),转变为图(2)之后发现,之前的job一定在图2中的某一条边上,同一条边上可以包含多个job,所以要完成所有的job,只需要包含所有的边即可,这就是最小点覆盖问题了。又知道二分图的最小点覆盖数=最大匹配数,因此可以用匈牙利算法求。(详细二分图关系见:)
cpp代码:


#include <cstdio>
#include 
<memory.h>

bool g[110][110]; //标记二分图的链接关系 
int match[110];//标记v中顶点匹配u的情况,无匹配则为-1 
int vis[110];
int n,m,k;

/**********************/
int SearchPath(int u)
{
    
for (int v = 1; v <= m; v ++)
        
if (g[u][v] && !vis[v])
        {
            vis[v] 
= true;
            
if (match[v] == -1 || SearchPath(match[v]))
            {
                 match[v] 
= u;
                 
return 1;
            }
        }
    
return 0;
}
                
/**********************************/

int main()
{
    
int i,j,x,y,ans;
    
while (scanf("%d",&n) && n != 0)
    {
          scanf(
"%d %d"&m, &k);
          
for (i = 1; i <= n; i++)
              
for (j = 1; j <= m; j ++)
                  g[i][j] 
= false;
              
          
for (i = 1; i <= k; i ++)
          {
              scanf(
"%d %d %d"&j, &x, &y);
              g[x][y] 
= true
          }
/**********/
          memset(match,
-1,sizeof(match));
          ans 
= 0;
          
for (i = 1; i <= n; i++)
          {
              memset(vis,
false,sizeof(vis));
              ans 
+= SearchPath(i);
          } 
                
/**************************/
          printf(
"%d\n",ans);   
          
    }
    
    
return 0;
}

你可能感兴趣的:(poj_Machine Schedule(匈牙利算法初步))