HDU-1498二分最大匹配

题目大意;对n*n的气球执行k次操作,每次操作可以击破一排或一列气球,输出k次操作后未能完全击破的气球编号,注意按循序输出。如果没有则输出-1。
解题思路:用二分匹配求出每种气球的最大匹配Mi,如果Mi大于k,则输出气球编号,如果没有Mi大于k,则输出-1;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int map[101][101],dis[101],flag[101],balloons[101],f[101];
int n,m,k;
int dfs(int t,int p)//二分匹配 p为气球编号
{
     for(int i=1; i<=n; i++)
    {
      if(!flag[i]&&map[t][i]==p)//模式与一般的二分匹配差不多,把map[][]=1,改成=p;
        {
            flag[i]=1;
            if(dis[i]==-1||dfs(dis[i],p))
            {
                dis[i]=t;
                return 1;
            }
        }
    }
    return 0;
}
int maxn(int p)
{
    int sum=0;
    memset(dis,-1,sizeof(dis));
    for(int i=1; i<=n; i++)
    {
        memset(flag,0,sizeof(flag));
        if(dfs(i,p))
            sum++;
    }

    return sum;
}
int main()
{
    int i,j,mark,flags;
    while(cin>>n>>m)
    {
        if(n==0&&m==0)break;
        memset(balloons,0,sizeof(balloons));//初始化为0,记录气球编号
        k=0;
        mark=0;flags=0;
        for(i=1; i<=n; i++)
            for(j=1; j<=n; j++)
            {
                cin>>map[i][j];
                if(balloons[map[i][j]]==0)//如果气球未出现过,则做记录
                {
                    balloons[map[i][j]]=1;
                    f[k++]=map[i][j];//把气球编号存入数组f中
                }
            }
            sort(f,f+k);//对号码排序
        for( j=0; j<k; j++)
        {
            if(maxn(f[j])>m)
            {
                 if(flags)//注意输出格式,最后一个不要空格
             cout<<" ";
                cout<<f[j];
               flags=1;
                mark=1;//如果有没能完全击破的气球,则不用输出-1
            }
        }
        if(!mark)cout<<"-1";//没有选择,则输出-1
        cout<<endl;


    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值