匈牙利算法二分图最大匹配

#include<bits/stdc++.h>
using namespace std;
const int N=300+10;
int p,n,g[N][N],linked[N],v[N];
int dfs(int u){
    for(int i=1; i<=n; i++)//逐个学生扫
        if(!v[i]&&g[u][i]){//未访问且有边
            v[i]=1;//设为已访问
            if(linked[i]==-1||dfs(linked[i])){
                linked[i]=u;return 1;
            }
        }
    return 0;
}
void hungary(){
    int num=0,i;
    memset(linked,-1,sizeof(linked));
    for(i=1; i<=p; i++){
        memset(v,0,sizeof(v));//每次都重置
   			if(dfs(i)) num++;
    }//逐堂课深搜若能满足则NUM+1
    if(num==p) printf("YES\n");
    else printf("NO\n");
}
int main(){
    int t,i,j,x;scanf("%d",&t);
    while(t--){
        scanf("%d%d",&p,&n);
        memset(g,0,sizeof(g));
        for(i=1; i<=p; i++){
            scanf("%d",&x);
            while(x--){
                scanf("%d",&j);
                g[i][j]=1;
            }
        }
        if(p>n){//课比学生多
            printf("NO\n");
            continue;
        }
        hungary();
    }
    return 0;
}
匈牙利算法
用途:二分图最大匹配

解释:
dfs(int u)中
对编号为u的课逐个学生进行扫描,如果在本课深搜过程中未visit过且课与学生有边时,就设置学生为已visit,然后看在全局状态下是否被link,没有link就设置其link连向本课,并返回1表示成功,如果被link就对其link的课进行深搜



hungary()中
linked是当前状态学生的连接状态,-1是未连,否则值为所连接的课的编号
v是在本节课在深搜时是否visit过的标志,所以每节课开始搜时都要重置





题目:HDU1083
有p门课n个学生,每门课都有若干学生,现在要为每个课程分配一名课代表,每个学生只能担任一门课的课代表,如果每个课都能找到课代表,则输出"YES",否则"NO"。
Input		output
2			YES
3 3			NO
3 1 2 3
2 1 2
1 1
3 3
2 1 3
2 1 3
1 1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值