二分图之最大匹配

来源:互联网 发布:百分百qq采集软件 编辑:程序博客网 时间:2024/05/17 07:29

最大匹配问题

题目描述:

给你p门课程和n个学生,一个学生可以选0门,1门,或者多门课程,现在要求一个由p个学生组成的集合,满足下列2个条件:

1.每个学生选择一个不同的课程

2.每个课程都有不同的代表

如果满足,就输出YES,否则输出NO。

 

  题目连接: http://poj.org/problem?id=1469

 

分析:

人和科目分别看成两个集合,求他们的最大匹配,用匈牙利算法。

 

算法代码:

#include <iostream>using namespace std;#include<cstdio>#define MAXN 310       // 实际问题时需要修改int  mat[MAXN][MAXN];    // 邻接矩阵mat 的0行0列不用 int  nx, ny;                         // 实际问题时矩阵的行列数 int  fy[MAXN], matx[MAXN], maty[MAXN]; int  path( int  u ) {     int v;       for (v=1;v<=ny;v++)            if (mat[u][v] && fy[v]<0)            {         fy[v]=1;                      if (maty[v]<0 || path(maty[v]))                      {   matx[u]=v;    maty[v]=u;   return 1;   }           }       return 0; }  int MaximumMatch( )                         //匈牙利算法{ int  i, ret=0; memset(matx,-1,sizeof(matx));           // 数组赋值为-1  memset(maty,-1,sizeof(maty));           // 数组赋值为-1  for (i=1;i<=nx;i++) if (matx[i]<0)  {   memset(fy,-1,sizeof(fy));           // 数组赋值为-1      ret+=path(i);   } return ret;} int main(int argc, char *argv[]){ int cas,i,j,k,l; scanf("%d",&cas); while(cas--) {  memset(mat,0,sizeof(mat));      // 清零   scanf("%d%d",&nx,&ny);  for(i=1;i<=nx;i++)  {   scanf("%d",&j);   while(j--)   {   scanf("%d",&k);    mat[i][k]=1;   }  }   if(MaximumMatch( )==nx)     //科目数是否等于最大匹配数    cout<<"YES"<<endl;   else cout<<"NO"<<endl;  } return 0;}


 

原创粉丝点击