#include <iostream>
using namespace std;
const int maxn=2e5;
int L[maxn];//左方向的链表
int R[maxn];//右方向的链表
int U[maxn];//上方向的链表
int D[maxn];//下方向的链表
int C[maxn];//指向列指针头的地址
int S[maxn];//记录列的节点个数
int O[maxn];//result
int head=0;
void remove(const int &c){
//remove col c and all row i that A[i][c]==1
L[R[c]]=L[c];
R[L[c]]=R[c];//双向链表操作
for(int i=D[c];i!=c;i=D[i]){
//remove i that A[i][c]==1
for(int j=R[i];j!=i;j=R[j]){
U[D[j]]=U[j];
D[U[j]]=D[j];
--S[C[j]];//decrease the count of col C[j]
}
}
}
void resume(const int &c){
for(int i=U[c];i!=c;i=U[i]){
for(int j=L[i];j!=i;j=L[i]){
++S[C[j]];
U[D[j]]=j;
D[U[j]]=j;
}
}
L[R[c]]=c;
R[L[c]]=c;
}
bool dfs(const int &k){
if(R[head]==head){
return true;
}
int s=1e9;
int c;
for(int t=R[head];t!=head;t=R[t]){
if(S[t]<s){
s=S[t];
c=t;
}
}//选一个列最少为清的出来
remove(c);
for(int i=D[c];i!=c;i=D[i]){
O[k]=i;
for(int j=R[i];j!=i;j=R[i]){
remove(C[j]);
}
if(dfs(k+1)){
return true;
}//继续递归下去
for(int j=L[i];j!=i;j=L[j]){
resume(C[j]);
}//不可行返回
}
resume(c);
return false;
}
总结:1.L[R[c]]=c;
R[L[c]]=c;
双向链表的增加操作
2.U[D[j]]=U[j];
D[U[j]]=D[j];
双向链表的删除操作
3.该段代码解决的是一个1101
0011
1100这样一个矩阵选特定的几行样每一列都有一个1
则代码中的dfs是选定列最小的出来来进行选取,加快代码运行的速度,这就是代码做出的优化,这道题是参考
递归求解问题转过来的 http://www.cnblogs.com/steady/archive/2011/03/15/1984791.html