获取中...

-

Just a minute...

122

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
struct DLX
{
int n,m,si;//n:row,m:col,si:node number
int U[MAX],D[MAX],L[MAX],R[MAX],row[MAX],col[MAX];//i node it and row and col
//行头结点->right和->left分别指向第i行的第一个“1”和最后一个“1”对应的结点

//列头节点->down和->up分别指向第i列的第一个“1”和最后一个“1”对应的结点
int H[MAX_1],S[MAX_1];//记录行的选择情况和列的覆盖情况
int ansd,ans[MAX];
void init(int nn,int mm)
{
n = nn;
m = mm;
for(int i = 0;i <= m;i ++)//列的头结点
{
S[i] = 0;//都没有被覆盖
U[i] = D[i] = i;//列是空的,都指向自己
L[i] = i-1;//横向的链连起来
R[i] = i+1;
}
L[0] = m;//连成一个环
R[m] = 0;
si = m;//当前有了si个节点
for(int i = 1;i <= n;i++)
{
H[i] = -1;//最开始行都没
}
}
void link(int r,int c)//insert node(r,c)//怎么操作的
{
col[++si] = c;//增加一个节点si+1,并且所在的列为c
S[c]++;//c列的1的数量++
row[si] = r;//所在的行为r

//D[c]:c列的第一个1
//U[c]:c列的最后一个1
U[si] = U[c];//节点的上指针指向上一个1
D[si] = c;//节点的下指针指向列头结点
D[U[c]] = si;//当前列的上一个1的下指针指向si
U[c] = si;//c列头结点的上指针指向si,该列的最后一个1

if(H[r] < 0)//还没有节点
H[r] = L[si] = R[si] = si;//指向自己,h[r]代表本行第一个元素
else
{
R[si] = H[r];//最右边的节点的右指针指向第一个节点
L[si] = L[H[r]];//最右边的节点的左指针指向前一个节点

R[L[H[r]]] = si;//前一个节点的右指针指向当前节点
L[H[r]] = si;//第一个节点的左指针指向当前节点
}
}
void myremove(int c)//delete c col
{
L[R[c]] = L[c];//右边节点的左节点从塔变为他的左节点
R[L[c]] = R[c];
for(int i = D[c];i != c;i = D[i])
{
for(int j = R[i];j != i;j = R[j])
{
U[D[j]] = U[j];//上下断开
D[U[j]] = D[j];
--S[col[j]];//该列1元素--
}
}
}
void resume(int c)//添加第c列
{
for(int i = U[c];i != c;i = U[i])//和删除的时候的方向是反着的
{
for(int j = L[i];j != i;j = L[j])
{
U[D[j]] = D[U[j]] = j;
++S[col[j]];
}
}
L[R[c]] = R[L[c]] = c;//头结点重新连接
}
bool dance(int d)//深度d
{
if(R[0] == 0)//达到全覆盖,头结点指向头节点
{
ansd = d;
return 1;
}
int c = R[0];
for(int i = R[0];i != 0;i = R[i])
{
if(S[i] < S[c])
c = i;
}//选择包含1最少的一列
myremove(c);
for(int i = D[c];i != c;i = D[i])
{
ans[d] = row[i];
for(int j = R[i];j != i;j = R[j])//选了一行
myremove(col[j]);//移除这一行其他包含1的列
if(dance(d+1))//下一层
return 1;
for(int j = L[i];j != i ;j = L[j])//反移除
resume(col[j]);
}
resume(c);
return 0;
}

}answer;
相关文章
评论
分享
  • 专题-搜索

    专题-搜索
  • vim

    vim
  • ubuntu18.04双硬盘(ssd+机械)+双系统(win10+linux)

    安装最先一定要分清楚一件事情你的系统启动方式是什么 UEFI or BCD?看清楚再安装(百度怎么看) 安装参考链接: https://www.cnblogs.com/ERFishing/p/10050867.html 注意事项1....

    ubuntu18.04双硬盘(ssd+机械)+双系统(win10+linux)
  • NC-10

    NC-10
  • NC-9

    NC-9
  • NC-8

    NC-8
  • ECF-70-2

    Educational Codeforces Round 70 (Rated for Div. 2)A.You Are Given Two Binary Strings乘2^k次,其实就是把二进制左移了k位 加法就是对应位加就好了,然...

    ECF-70-2
  • NC-7

    2019牛客暑期多校训练营(第七场)A.String题目思路:其实就是要求一个字符串,把原串的后缀拼到前面的时候,每一种后缀拼完字典序都比原串大 然后题目给你一个s,问你s最少能切割为多少个这样的字符串 可以发现,这样的串一定是0开头...

    NC-7
  • CF-577-2

    Codeforces Round #577 (Div. 2)A.Important Exam问学生分数总和最大为多少 那么就是每道题选的最多的选项为答案,计算即可 B.Zero Array如果sum是奇数的一定不行 如果是偶数的话就看...

    CF-577-2
  • NC-6

    2019牛客暑期多校训练营(第六场)A.Garbage Classification就用map统计一下每种垃圾有多少个 然后在进行分类,看看每个类型的垃圾有多少个 最后就根据题意分类就好了 B.Shorten IPv6 Address...

    NC-6
Please check the parameter of comment in config.yml of hexo-theme-Annie!