匈牙利算法

#include<bits/stdc++.h>
#define ll long long 
#define scan(i) scanf("%d",&i)
#define scand(i) scanf("%lf",&i)
#define scanl(i) scanf("%lld",&i)
#define f(i,a,b) for(int i=a;i<=b;i++) 
#define pb(i) push_back(i)
#define ppb pop_back()
#define pf printf
using namespace std;
int t,n,k; 
int m[102][102]; 
set<int> color;
set<int> no;
int curcolor;
bool edge[102][102];
bool vis[102];//女孩有主否 
int col[102];
bool find(int x){//x能否找到伴侣 
    f(i,1,n){
        if(edge[x][i]==true&&vis[i]==false){
            vis[i]=true;
            if(col[i]==0||find(col[i])==true){
                col[i]=x;
                return true;
            }
        }
    }
    return false;
}
int maxmatch(){//返回二分图匹配最大数 
    memset(col,0,sizeof(col));
    int ans=0;
    f(i,1,n){
        memset(vis,0,sizeof(vis));
        if(find(i)) ans++;
    }
    return ans;
}
int main(){
    while(scanf("%d%d",&n,&k)!=EOF){
        if(n==0&&k==0) return 0;
        no.clear();
        f(i,1,n){
            f(j,1,n) scan(m[i][j]),color.insert(m[i][j]);
        }
        if(k>=n){
            pf("-1\n");
            continue;
        }
        auto point=color.begin();
        while(point!=color.end()){
            memset(edge,0,sizeof(edge));
            curcolor=*point;
            point++;
            f(i,1,n){
                f(j,1,n){
                    if(m[i][j]==curcolor){
                        edge[i][j]=true;
                    }
                }
            }
            if(maxmatch()>k) no.insert(curcolor);
        }
        
        if(no.empty()){
            pf("-1\n");
            continue;
        }
        else{
            auto it=no.begin();
            pf("%d",*it);
            it++;
            for(;it!=no.end();it++){
                pf(" %d",*it);
            }
            putchar('\n');
        }
        //pf("Case #%d: %lld\n",kk,ans);
    }
    return 0;
} 

二分图匹配问题,我以HDU balloon 1498为例

转载于:https://www.cnblogs.com/St-Lovaer/p/11422788.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值