hdu 1498 匈牙利算法

http://acm.hdu.edu.cn/showproblem.php?pid=1498

这道题目昨天晚上做了很久,题目意思没看懂,后来看了些网上代码,算是彻底懂了。其实是每个学生可以选择其中一种气球来踩,后面还有很多学生在排队。就是有多少种颜色的气球就有多少个学生来踩,当每种颜色的气球都被踩过K次以后,问:还有哪几种颜色的气球存在。

刚开始做了一遍,发现重复输出了好多。后来看见别人用了set容器,自己也跟着用了,提交46ms,本以为很优来了,搜下神牛的代码,发现了一个15ms的,汗。

其实人家算法和我是一样的,只不过人家用两个数组记录   等于   我的set容器。以后要少用set容器之类的系统模板,因为这样或多或少影响了我的编程能力与代码的灵敏性。。。

下面是我的代码46ms:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<set>
using namespace std;
#define maxn 105
#define mem(str,x) memset(str,(x),sizeof(str))
int map[maxn][maxn];
bool vis[maxn];
int flag[maxn][maxn];
int per[maxn];
int ans[maxn];
int n,k;
bool find(int x)
{
    for(int i=1;i<=n;i++){
        if( !vis[i] && flag[x][i] ){
                vis[i] = true;
            if(per[i] == -1 || find( per[i] ) ){
                per[i] = x;
                return true;
            }
        }
    }
    return false;
}
int hungry()
{
    int sum=0;
    for(int i=1;i<=n;i++) per[i] = -1;
    for(int i=1;i<=n;i++){
            mem(vis,false);
         sum+=find(i);
    }
    return sum;
}
int main()
{
     set< int > v;
    while(scanf("%d%d",&n,&k)&&n!=0&&k!=0){
            mem(map,0);  v.clear(); mem(ans,0);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                    int x;
                scanf("%d",&x);
                map[i][j] = x;
                v.insert( map[i][j] );
            }
        }
        if( k >= n ) printf("-1\n");
        else{
                int anss=0;
             set<int>::iterator it;///定义前向迭代器
           for(it = v.begin(); it != v.end(); it++ ){
               int color = *it;
               mem(flag,0);
               for(int i=1;i<=n;i++)
               for(int j=1;j<=n;j++){
                   if(map[i][j] == color)
                       flag[i][j] = 1;
                   else
                       flag[i][j] = 0;
               }
               int sum = hungry();
               if(sum > k) ans[anss++] = color;
           }
           if(anss==0) printf("-1\n");
           else{
            for(int i = 0;i <anss;i++ ){
                printf("%d%c",ans[i],(i==anss-1)?'\n':' ');
            }
           }
        }
    }
    return 0;
}

下面是神牛代码15ms:

#include"stdio.h" 
#include"string.h" 
#include"stdlib.h" 
int map[101][101],mark[101]; 
int v[101],link[101]; 
int a[101],color[101]; 
int k,n; 
int cmp(const void*a,const void*b) 
{ 
    return *(int*)a-*(int*)b; 
} 
int dfs(int i,int k) 
{ 
    int j; 
    for(j=1;j<=n;j++) 
    { 
        if(map[i][j]==k&&!v[j]) 
        { 
            v[j]=1; 
            if(link[j]==0||dfs(link[j],k)) 
            { 
                link[j]=i; 
                return 1; 
            } 
        } 
    } 
    return 0; 
} 
int main() 
{ 
    int i,j,t,tt,ans; 
    while(scanf("%d%d",&n,&k)!=-1) 
    { 
        if(n==0&&k==0) 
            break; 
        memset(color,0,sizeof(color)); 
        memset(mark,0,sizeof(mark)); 
        t=0; 
        for(i=1;i<=n;i++) 
        { 
            for(j=1;j<=n;j++) 
            { 
                scanf("%d",&map[i][j]); 
                if(!mark[map[i][j]]) 
                { 
                    mark[map[i][j]]=1; 
                    color[t++]=map[i][j]; 
                } 
            } 
        } 
        tt=0; 
        for(i=0;i<t;i++) 
        { 
            ans=0; 
            memset(link,0,sizeof(link)); 
            for(j=1;j<=n;j++) 
            { 
                memset(v,0,sizeof(v)); 
                if(dfs(j,color[i])) 
                    ans++; 
            } 
            if(ans>k) 
                a[tt++]=color[i]; 
        } 
        if(tt==0) 
            printf("-1\n"); 
        else 
        { 
            qsort(a,tt,sizeof(a[0]),cmp); 
            for(i=0;i<tt-1;i++) 
                printf("%d ",a[i]); 
            printf("%d\n",a[i]); 
        } 
    } 
    return 0; 
}


其实还有好多0ms的神牛。。。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值