建立精确覆盖模型求解(Dancing Links)~

View Code
1 #include <cstdio>
2 #include <cstring>
3 #include <algorithm>
4
5  using namespace std;
6
7  const int MAXR = 1024;
8 const int MAXC = 512;
9 const int SIZE = 1024;
10 const int INF = (1 << 20);
11
12 struct Node
13 {
14 Node * u;
15 Node * d;
16 Node * l;
17 Node * r;
18 int rnum;
19 int cnum;
20 };
21
22 int node;
23 int sum[MAXC];
24 Node head;
25 Node row[MAXR];
26 Node column[MAXC];
27 Node pool[MAXR * MAXC];
28
29 int alen;
30 int ans[MAXR];
31
32 void InitDLX(int nr,int nc)
33 {
34 node = 0;
35 memset(sum,0,sizeof(sum));
36 head.r = &column[0];
37 column[0].cnum = 0;
38 column[0].l = &head;
39 column[0].u = column[0].d = &column[0];
40 for (int i = 1; i < nc; i++)
41 {
42 column[i].cnum = i;
43 column[i-1].r = &column[i];
44 column[i].l = &column[i-1];
45 column[i].u = column[i].d = &column[i];
46 }
47 column[nc-1].r = &head;
48 head.l = &column[nc-1];
49
50 for (int i = 0; i < nr; i++)
51 row[i].l = row[i].r = &row[i];
52 }
53
54 void InsertDLX(int r,int c)
55 {
56 sum[c]++;
57 pool[node].rnum = r;
58 pool[node].cnum = c;
59 pool[node].l = row[r].l;
60 pool[node].r = &row[r];
61 row[r].l->r = &pool[node];
62 row[r].l = &pool[node];
63 pool[node].u = column[c].u;
64 pool[node].d = &column[c];
65 column[c].u->d = &pool[node];
66 column[c].u = &pool[node];
67
68 node++;
69 }
70
71 void DeleteRowHeadDLX(int nr)
72 {
73 for (int i = 0; i < nr; i++)
74 {
75 row[i].l->r = row[i].r;
76 row[i].r->l = row[i].l;
77 }
78 }
79
80 void RemoveColumn(Node * col)
81 {
82 col->l->r = col->r;
83 col->r->l = col->l;
84 for (Node * p = col->d; p != col; p = p->d)
85 for (Node * q = p->r; q != p; q = q->r)
86 {
87 q->u->d = q->d;
88 q->d->u = q->u;
89 sum[q->cnum]--;
90 }
91 }
92
93 void ResumeColumn(Node * col)
94 {
95 col->l->r = col;
96 col->r->l = col;
97 for (Node * p = col->d; p != col; p = p->d)
98 for (Node * q = p->r; q != p; q = q->r)
99 {
100 q->u->d = q;
101 q->d->u = q;
102 sum[q->cnum]++;
103 }
104 }
105
106 bool dfs(int k)
107 {
108 if (head.r == &head)
109 {
110 alen = k;
111 return true;
112 }
113
114 int minl = INF;
115 Node * mincol;
116 for (Node * p = head.r; p != &head; p = p->r)
117 if (sum[p->cnum] < minl)
118 {
119 minl = sum[p->cnum];
120 mincol = p;
121 }
122 RemoveColumn(mincol);
123 for (Node * p = mincol->d; p != mincol; p = p->d)
124 {
125 for (Node * q = p->r; q != p; q = q->r)
126 RemoveColumn(&column[q->cnum]);
127 if (dfs(k + 1))
128 {
129 ans[k] = p->rnum;
130 return true;
131 }
132 for (Node * q = p->l; q != p; q = q->l)
133 ResumeColumn(&column[q->cnum]);
134 }
135 ResumeColumn(mincol);
136 return false;
137 }
138
139 bool gmap[SIZE][SIZE];
140
141 int lable[SIZE];
142
143 int main()
144 {
145 int nv;
146 int ne;
147 int nd;
148
149 int nr;
150 int nc;
151
152 int u;
153 int v;
154 int o;
155
156 while(scanf("%d %d %d",&nv,&ne,&nd) != EOF)
157 {
158 nr = 0;
159 nc = nv + nd * nv;
160 memset(gmap,false,sizeof(gmap));
161
162 for(int i = 0; i < ne; i++)
163 {
164 scanf("%d %d",&u,&v);
165 gmap[u - 1][v - 1] = gmap[v - 1][u - 1] = true;
166 }
167
168 for(int i = 0; i < nv; i++)
169 gmap[i][i] = true;
170
171 for(int i = 0; i < nv; i++)
172 {
173 scanf("%d %d",&u,&v);
174
175 u--;
176 v--;
177
178 for(int s = u; s <= v; s++)
179 for(int e = s; e <= v; e++)
180 lable[nr++] = i * 100 + s * 10 + e;
181
182 lable[nr++] = i * 100 + nd * 10 + nd;
183 }
184
185 InitDLX(nr,nc);
186
187 for(int i = 0; i < nr; i++)
188 {
189 o = lable[i] / 100;
190 u = (lable[i] % 100) / 10;
191 v = lable[i] % 10;
192
193 InsertDLX(i,o);
194
195 if(u == nd && v == nd) continue;
196
197 for(int j = 0; j < nv; j++)
198 if(gmap[o][j])
199 for(int k = u; k <= v; k++)
200 InsertDLX(i,nv + j * nd + k);
201 }
202
203 DeleteRowHeadDLX(nr);
204
205 if(!dfs(0)) printf("No solution\n");
206 else
207 {
208 sort(ans,ans + alen);
209 for(int i = 0; i < alen; i++)
210 {
211 u = (lable[ans[i]] % 100) / 10;
212 v = lable[ans[i]] % 10;
213 if(u == nd && v == nd) printf("0 0\n");
214 else printf("%d %d\n",u + 1,v + 1);
215 }
216 }
217 printf("\n");
218 }
219 return 0;
220 }