• hdu 1498 50 years, 50 colors (二分匹配)


    点击打开链接

    题意: 
     给你一个n*n的矩阵,在矩阵中分布着s种颜色的气球,给你k次扎破气球
     的操作,每次操作可以扎破一行,或一列的同一颜色的气球。问在k次操
     作后有那几种颜色的气球是不能被完全扎破的. 
    解题:
      利用二分图匹配,寻找每一种颜色对应的最大匹配(行和列分别为A集合,B集合;M[i,j]代表一个搭配),
      如果大于k则输出"-1",否则输出颜色的递增序列 
    注:在二分图中求最少的点,让每条边都至少和其中的一个点关联,这就是
    二分图的“最小顶点覆盖”。  
    #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;
    }



  • 相关阅读:
    Hibernate入门
    oracle数据库应用(2)
    oracle数据库应用
    Oracle数据库基础
    InitBinder 在Controller方法执行之前进行捕获请求,进行类型的转换
    Spring面试题
    Object处理方法的返回值
    使用jQuery快速高效制作网页交互特效
    struts2
    表分区
  • 原文地址:https://www.cnblogs.com/yyf573462811/p/6365281.html
Copyright © 2020-2023  润新知