• pku 1469 COURSES


    http://poj.org/problem?id=1469

    题目是说有几门课程和几个学生,让你求的学生和课程之间的最大匹配数是否和所给的课程数目相等。如果相等输出“YES” 否则,输出“NO“

    下面这就是一个二分图

    二分图模型   
    二分图模型

    二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集。给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配.   选择这样的边数最大的子集称为图的最大匹配问题(maximal matching problem)

    求二分图的最大匹配的算法就是匈牙利算法  这里有详细的讲解,可以去看一下http://hi.baidu.com/ensteinniesen/blog/item/7ea41aeaa0c783c1d539c94a.html

    匈牙利算法的模板

     1 二分图最大匹配问题的匈牙利算法:
    2
    3 #define N 202
    4 int useif[N]; //记录y中节点是否使用
    5 int link[N]; //记录当前与y节点相连的x的节点
    6 int mat[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
    7 int gn,gm; //二分图中x和y中点的数目
    8 int can(int t)
    9 {
    10 int i;
    11 for(i=1;i<=gm;i++)
    12 {
    13 if(useif[i]==0 && mat[t][i])
    14 {
    15 useif[i]=1;
    16 if(link[i]==-1 || can(link[i]))
    17 {
    18 link[i]=t;
    19 return 1;
    20 }
    21 }
    22 }
    23 return 0;
    24 }
    25 int MaxMatch()
    26
    27 {
    28 int i,num;
    29 num=0;
    30 memset(link,0xff,sizeof(link));
    31 for(i=1;i<=gn;i++)
    32 {
    33 memset(useif,0,sizeof(useif));
    34 if(can(i)) num++;
    35 }
    36 return num;
    37 }

    下面就是这道题目的代码了

     1 #include<stdio.h>
    2 #include<string.h>
    3 #include<iostream>
    4 using namespace std;
    5 #define M 300
    6 int map[M][M],v[M],m[M];
    7 int p,n;
    8 int match(int k)
    9 {
    10 int i;
    11 for(i=1;i<=n;i++)
    12 {
    13 if(map[k][i]&&!v[i])
    14 {
    15 v[i]=1;
    16 if(m[i]==-1||match(m[i]))
    17 {
    18 m[i]=k;
    19 return 1;
    20 }
    21 }
    22 }
    23 return 0;
    24 }
    25 int main()
    26 {
    27 int t,i;
    28 cin>>t;
    29 while(t--)
    30 {
    31 memset(map,0,sizeof(map));
    32 memset(m,-1,sizeof(m));
    33 cin>>p>>n;
    34 int k,x;
    35 for(i=1;i<=p;i++)
    36 {
    37 scanf("%d",&k);//cin>>k;
    38 while(k--)
    39 {
    40 scanf("%d",&x);
    41 //cin>>x;
    42 map[i][x]=1;
    43 }
    44 }
    45 int sum=0;
    46 for(i=1;i<=p;i++)
    47 {
    48 memset(v,0,sizeof(v));
    49 if(match(i)) sum++;
    50 }
    51 if(sum==p) cout<<"YES\n";
    52 else cout<<"NO\n";
    53 }
    54 return 0;
    55 }



  • 相关阅读:
    表单数据源控制器笔记
    方法汇总1
    Persistence.beans
    数据库外键理解
    SQL语句缺少
    树型结构需要绑定的字段
    模型绑定替换
    乱码
    表单的验证:客户端验证和服务器端验证
    表单
  • 原文地址:https://www.cnblogs.com/fxh19911107/p/2383903.html
Copyright © 2020-2023  润新知