给一个矩阵,里面有一些不同颜色的气球,每次可以消灭一行或一列中某一种颜色的气球,问你在k次及以内,有哪些颜色的气球是无论如何也消不完的。
那么思路就是,对每一种颜色的气球求最小点覆盖,>k 则为答案。
相当于
poj3041 的加强版,因为矩阵中不是每一个点都是等价的。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<map> const int maxn=105; using namespace std; int mx[maxn],my[maxn],vis[maxn],e[maxn][maxn],n,cnt,mp[maxn][maxn],mat[maxn],ans[maxn]; map<int,int> mmp; int path(int i) { int j; for(j=0;j<n;j++) { if(e[i][j]&&!vis[j]) { vis[j]=1; if(my[j]==-1||path(my[j])) { mx[i]=j; my[j]=i; return 1; } } } return 0; } int hungry() { int res=0; memset(mx,-1,sizeof mx); memset(my,-1,sizeof my); for(int i=0;i<n;i++) { if(mx[i]==-1) { memset(vis,0,sizeof vis); res+=path(i); } } return res; } int main() { int k,i,j,m,p,x; while(scanf("%d%d",&n,&k)&&(n||k)) { cnt=1; mmp.clear(); for(i=0;i<n;i++) for(j=0;j<n;j++) { scanf("%d",&mp[i][j]); if(mmp[mp[i][j]]) continue; else { mmp[mp[i][j]]=cnt; mat[cnt++]=mp[i][j]; } } m=0; for(p=1;p<cnt;p++) { x=mat[p]; memset(e,0,sizeof e); for(i=0;i<n;i++) for(j=0;j<n;j++) if(mp[i][j]==x) e[i][j]=1; if(hungry()>k) ans[m++]=x; } if(m==0) printf("-1\n"); else { sort(ans,ans+m);//wa了一次。。 printf("%d",ans[0]); for(i=1;i<m;i++) printf(" %d",ans[i]); puts(""); } } return 0; }
hdu1498 50 years, 50 colors --- 最小点覆盖,布布扣,bubuko.com
hdu1498 50 years, 50 colors --- 最小点覆盖
原文地址:http://blog.csdn.net/u011032846/article/details/38031907