每次只能消除一行或一列的相同颜色的气球,
求有多少种气球在k次内不能消除
求出每种气球最少需要多少次消除,就跟hdu 2119消除1用多少次是一样
将行和列分别看成二分图的两个集合,每个气球都是一条边,用最少的点覆盖所有相同颜色的边,最小顶点覆盖
#include<stdio.h> #include<string.h> #include<stdlib.h> int map[101][101],link[101],color[55],mark[101],n,c[55]; int cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; } int find(int i,int colo) { int j; for(j=1;j<=n;j++) { if(map[i][j]==colo&&mark[j]==0) { mark[j]=1; if(link[j]==0||find(link[j],colo)==1) { link[j]=i; return 1; } } } return 0; } int main() { int i,j,sum,k,temp,num; while(scanf("%d%d",&n,&k),n&&k) { temp=0; memset(map,0,sizeof(map)); memset(color,0,sizeof(color)); memset(mark,0,sizeof(mark)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { scanf("%d",&map[i][j]); if(mark[map[i][j]]==0) { color[temp++]=map[i][j]; mark[map[i][j]]=1; } } num=0; for(i=0;i<temp;i++) { memset(link,0,sizeof(link)); sum=0; for(j=1;j<=n;j++) { memset(mark,0,sizeof(mark)); sum=sum+find(j,color[i]); } if(sum>k) { c[num++]=color[i]; } } qsort(c,num,sizeof(c[0]),cmp); if(num==0) printf("-1\n"); else { printf("%d",c[0]); for(i=1;i<num;i++) printf(" %d",c[i]); printf("\n"); } } return 0; }