题意:给你一个n*n的矩阵,在矩阵中分布着s种颜色的气球,给你k次扎破气球的操作,每次操作可以扎破一行,或一列的同一颜色的气球。问在k次操作后有那几种颜色的气球是不能被完全扎破的.
思路:枚举每种颜色判断一下该颜色的气球最少需要多少次才能全部扎破。
对于每一种颜色都是行列匹配,求最小点覆盖 看是否大于k 最小点覆盖 = 最大匹配
链接:hdu 1498
#include #include #include #include #include #include #include #include #include #include #define INF 0x3f3f3f3f using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 2555; int used[maxn]; int link[maxn]; int mat[maxn][maxn]; int gn, gm; int x[maxn], y[maxn]; int dfs(int t, int y) { for(int i = 1; i <= gm; i++) { if(!used[i] && mat[t][i] == y) { used[i] = 1; if(link[i] == -1 || dfs(link[i], y)) { link[i] = t; return 1; } } } return 0; } int maxmatch(int y) { int num = 0; memset(link, 0xff, sizeof(link)); for(int i = 1; i <= gn; i++) { memset(used, 0, sizeof(used)); if(dfs(i, y)) { num++; } } return num; } int main() { int n, m, k, t, kcase = 0; while(~scanf("%d %d", &n, &k) && n && k){ memset(mat, 0, sizeof(mat)); memset(x, 0, sizeof(x)); gn = n; gm = n; int a; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { scanf("%d", &a); mat[i][j] = a; x[a] = 1; } } for(int i = 1; i <= 50; i++) { if(x[i]) { int res = maxmatch(i); if(res <= k) { x[i] = 0; } } } int flag = 1; for(int i = 1; i <= 50; i++) { if(x[i]) { if(!flag) printf(" "); printf("%d", i); flag = 0; } } if(!flag) puts(""); else puts("-1"); } return 0; }