【二分图匹配(最小顶点覆盖)】hdu 1498 50 years,50 colors

来源:互联网 发布:linux服务开机自启动 编辑:程序博客网 时间:2024/05/23 14:58

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

题意:有n*n个不同颜色的气球,每次只能扎破同一行或者同一列相同颜色的气球,问在k次操作后哪种颜色的气球还剩下

分析:需要用最少的次数扎破同一颜色的气球,把行和列看成二分图的两组集合,进行最大匹配,转化成求最小顶点覆盖


#include <iostream>#include <cstdio>#include <cstring>#include <queue>using namespace std;const int NM=105;int a[NM][NM][NM],flag[NM],fs[NM],link[NM],n;int Find(int t,int x){for(int i=1;i<=n;i++){if(a[t][x][i]&&!flag[i]){flag[i]=1;if(link[i]==-1||Find(t,link[i])){link[i]=x;return true;}}}return false;}int main(){int i,j,k,t,ans;while(scanf("%d%d",&n,&k)&&(n||k)){memset(fs,0,sizeof(fs));memset(a,0,sizeof(a));for(i=1;i<=n;i++)for(j=1;j<=n;j++){scanf("%d",&t);fs[t]=1;a[t][i][j]=1;}queue<int>q1;for(i=1;i<=50;i++){if(!fs[i]) continue;memset(link,-1,sizeof(link));ans=0;for(j=1;j<=n;j++){memset(flag,0,sizeof(flag));if(Find(i,j)) ans++;}if(ans>k) q1.push(i);}if(!q1.empty()) {cout<<q1.front();q1.pop();}else printf("-1");while(!q1.empty()){cout<<" "<<q1.front();q1.pop();}printf("\n");}return 0;}/*5 31 1 2 1 11 2 2 1 12 1 2 1 21 1 2 1 11 1 1 1 115 41 2 3 4 12 3 4 5 13 4 5 1 24 5 1 2 35 1 2 3 41 2 3 4*/


0 0
原创粉丝点击