题意:在M*N的矩阵中,每个元素为0或1,现在问你能否找到若干行,使得每一列只有1个1. 思路:bfs + 优先队列 源代码: #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int MAXN = 17; const int MAXM = 301; int matrix[MAXN][MAXM]; int link[MAXN][MAXN]; //判断i行和j行能否组合 int rowCnt[MAXN]; //rowCnt判断i行中1的总数 int m, n; struct node_T { int row[MAXN]; //记录已经合并哪些行 int rCnt; //记录行的记录数 int cnt; //记录列中1的总数 bool operator < (const node_T &nod) const //运算符重载 { return cnt < nod.cnt; } }; bool bfs() { priority_queue<node_T> Q; //优先级队列 node_T cur, tmp; int i, j; for(i = 0; i < m; i ++) { cur.row[0] = i; //初始化队列,每行入队列 cur.rCnt = 1; cur.cnt = rowCnt[i]; Q.push(cur); } while(! Q.empty()) { cur = Q.top(); Q.pop(); if(cur.cnt == n) return true; tmp = cur; for(i = cur.row[cur.rCnt - 1] + 1; i < m; i ++) { for(j = 0; j < cur.rCnt; j ++) { if(! link[i][cur.row[j]]) //两行可以放在一起 break; } if(j == cur.rCnt) { tmp.rCnt = cur.rCnt + 1; //添加一行到结构中,记录在结构中 tmp.row[tmp.rCnt - 1] = i; tmp.cnt = cur.cnt + rowCnt[i]; Q.push(tmp); //加入队列中 } } } return false; } int main() { int i, j, k; while(scanf("%d%d", &m, &n) != EOF) { memset(rowCnt, 0, sizeof(rowCnt)); for(i = 0; i < m; i ++) { for(j = 0; j < n; j ++) { scanf("%d", &matrix[i][j]); rowCnt[i] += matrix[i][j]; } } for(i = 0; i < m; i ++) { link[i][i] = 0; for(j = i + 1; j < m; j ++) { for(k = 0; k < n; k ++) { if(matrix[i][k] & matrix[j][k]) break; } if(k < n) { link[i][j] = link[j][i] = 0; } else { link[i][j] = link[j][i] = 1; } } } if(bfs()) printf("Yes, I found it/n"); else printf("It is impossible/n"); } return(0); }