Herbin 1004 Power Stations
第35届ACM/ICPC亚洲区预选赛哈尔滨赛区的 1004 题,Power Stations。
Dancing Links,相对于其他的 DLX 来说,这道题目应该还算简单的。
添加几组测试数据:
输出: (spj题目,输出不唯一).
Dancing Links,相对于其他的 DLX 来说,这道题目应该还算简单的。
1
/*
2 * File: Herbin 1004 Power Stations
3 * Author: xiaotian @ hnu
4 * Created on 2010年9月29日, 下午12:24
5 * 题解:经典的 Dancing Links 精确覆盖题目。题目挂在杭电。
6 * 以每一个 town 的每一天分别为行和列去建图。见图应该是比较容易想到的,也比较裸。
7 * 某一个 town 在他工作的那个时间段可以覆盖他自己和及与他相邻的的 town 。以此为依据建图。
8 * 这道题麻烦在每一个 town 的 power station 只能用一次。
9 * 也就是说你不能先用一段时间关掉,再过一段时间后又打开。这样是不合法的。
10 * 那么就必须在搜索的过程中实时判断解的合法性。只要有一组解合法就可以了。具体见 dfs 函数。
11 */
12 #include < iostream >
13 #include < cstdio >
14 #include < string .h >
15 #include < vector >
16 #include < math.h >
17 #define inf 0x3fffffff
18 using namespace std;
19 const int N = 305 ;
20 const int M = 4000 ;
21 int map[N][N];
22 vector < int > g[ 65 ];
23 int out [N];
24 int beg[ 65 ], end[ 65 ];
25 int U[M], D[M], R[M], L[M], rs[N];
26 int size[N], head, row[M], col[M];
27 int n, m, k;
28 int nodecnt, maxdepth;
29 struct point
30 {
31 int x,y;
32 point( int xx = 0 , int yy = 0 ):x(xx),y(yy){}
33 };
34 point shu[ 65 ];
35 void read() {
36 int i, j;
37 for (i = 0 ; i <= n; i ++ ) {
38 g[i].clear();
39 g[i].push_back(i);
40 }
41 for (i = 0 ; i < m; i ++ ) {
42 int a, b;
43 scanf( " %d%d " , & a, & b);
44 a -- , b -- ;
45 g[a].push_back(b);
46 g[b].push_back(a);
47 }
48 for (i = 0 ; i < n; i ++ ) scanf( " %d%d " , beg + i, end + i);
49 }
50
51 void init( int m) {
52 memset(size, 0 , sizeof (size));
53 memset(col, - 1 , sizeof (col));
54 nodecnt = m + 1 ;
55 for ( int i = 0 ; i <= m; i ++ ) {
56 L[i] = (i - 1 );
57 R[i] = (i + 1 );
58 col[i] = i;
59 D[i] = U[i] = i;
60 }
61 L[ 0 ] = m;
62 R[m] = 0 ;
63 size[ 0 ] = INT_MAX;
64 }
65 int ans[N];
66 int len;
67 bool yes;
68
69 inline void remove( int id) {
70 int i, j;
71 R[ L[id] ] = R[id];
72 L[ R[id] ] = L[id];
73 for (i = D[id]; i != id; i = D[i])
74 for (j = R[i]; j != i; j = R[j]) {
75 U[ D[j] ] = U[j];
76 D[ U[j] ] = D[j];
77 size[ col[j] ] -- ;
78 }
79 }
80
81 inline void resume( int id) {
82 int i, j;
83 for (i = U[id]; i != id; i = U[i])
84 for (j = L[i]; j != i; j = L[j]) {
85 size[ col[j] ] ++ ;
86 U[ D[j] ] = j;
87 D[ U[j] ] = j;
88 }
89 R[ L[id] ] = id;
90 L[ R[id] ] = id;
91 }
92
93 int ansL;
94
95 int output() {
96 memset( out , 0 , sizeof ( out ));
97 for ( int i = 0 ; i < ansL; i ++ ) {
98 out [ans[i]] = 1 ;
99 }
100 for ( int i = 0 ; i < n; i ++ ) {
101 int a, b;
102 a = b = 0 ;
103 for ( int j = 1 ; j <= k; j ++ ) {
104 if (j == 1 ) {
105 if ( out [i * k + j] == 1 ) a = j;
106 } else {
107 if ( out [i * k + j] == 1 && out [i * k + j - 1 ] == 0 )
108 {
109 if (a) return 0 ;
110 else a = j;
111 }
112 }
113 if (j == k) {
114 if ( out [i * k + j] == 1 ) b = j;
115 } else {
116 if ( out [i * k + j] == 1 && out [i * k + j + 1 ] == 0 )
117 {
118 if (b) return 0 ;
119 else b = j;
120 }
121 }
122 }
123 shu[i] = point(a,b);
124 }
125 return 1 ;
126 }
127
128 void dfs1( int num) {
129 if (R[ 0 ] == 0 ) {
130 ansL = num;
131 yes = output();
132 if (yes)
133 {
134 for ( int i = 0 ;i < n;i ++ ) printf( " %d %d\n " ,shu[i].x,shu[i].y);
135 puts( "" );
136 }
137 return ;
138 }
139 int i, j, id = 0 , min = inf;
140 for (i = R[ 0 ]; i != 0 ; i = R[i])
141 if (size[i] < min) {
142 min = size[i];
143 id = i;
144 }
145 remove(id);
146 for (i = D[id]; i != id; i = D[i]) {
147 ans[num] = row[i];
148 for (j = R[i]; j != i; j = R[j])
149 remove(col[j]);
150 dfs1(num + 1 );
151 if (yes) return ;
152 for (j = L[i]; j != i; j = L[j])
153 resume(col[j]);
154 }
155 resume(id);
156 }
157
158 inline void insert( int i, int * tt, int c) {
159 for ( int j = 0 ; j < c; j ++ , nodecnt ++ ) {
160 int x = tt[j];
161 row[nodecnt] = i;
162 col[nodecnt] = x;
163 size[x] ++ ;
164 U[nodecnt] = x;
165 D[nodecnt] = D[x];
166 U[D[x]] = nodecnt;
167 D[x] = nodecnt;
168 if (j == 0 ) L[nodecnt] = R[nodecnt] = nodecnt;
169 else {
170 L[nodecnt] = nodecnt - 1 ;
171 R[nodecnt] = nodecnt - j;
172 R[nodecnt - 1 ] = nodecnt;
173 L[nodecnt - j] = nodecnt;
174 }
175 }
176 }
177
178 void build() {
179 init(n * k);
180 int tt[ 305 ], c = 0 ;
181 int t = n * k + 1 ;
182 for ( int i = 1 ; i < t; i ++ ) {
183 c = 0 ;
184 for ( int j = 1 ; j < t; j ++ )
185 if (map[i][j] == 1 ) tt[c ++ ] = j;
186 insert(i, tt, c);
187 }
188 }
189
190 void solve() {
191 memset(map, 0 , sizeof (map));
192 for ( int i = 0 ; i < n; i ++ ) {
193 for ( int j = beg[i]; j <= end[i]; j ++ ) {
194 for ( int a = 0 ; a < g[i].size(); a ++ ) {
195 map[i * k + j][g[i][a] * k + j] = 1 ;
196 }
197 }
198 }
199 memset( out , 0 , sizeof ( out ));
200 int flag = 0 ;
201 while (flag < 1 ) {
202 build();
203 ansL = inf;
204 yes = false ;
205 dfs1( 0 );
206 if (yes == false ) {
207 puts( " No solution\n " );
208 return ;
209 }
210 flag ++ ;
211 }
212 }
213
214 int main() {
215 // freopen("in.txt", "r", stdin);
216 // freopen("out.txt", "w", stdout);
217 while (scanf( " %d%d%d " , & n, & m, & k) != EOF) {
218 read();
219 solve();
220 }
221 return 0 ;
222 }
2 * File: Herbin 1004 Power Stations
3 * Author: xiaotian @ hnu
4 * Created on 2010年9月29日, 下午12:24
5 * 题解:经典的 Dancing Links 精确覆盖题目。题目挂在杭电。
6 * 以每一个 town 的每一天分别为行和列去建图。见图应该是比较容易想到的,也比较裸。
7 * 某一个 town 在他工作的那个时间段可以覆盖他自己和及与他相邻的的 town 。以此为依据建图。
8 * 这道题麻烦在每一个 town 的 power station 只能用一次。
9 * 也就是说你不能先用一段时间关掉,再过一段时间后又打开。这样是不合法的。
10 * 那么就必须在搜索的过程中实时判断解的合法性。只要有一组解合法就可以了。具体见 dfs 函数。
11 */
12 #include < iostream >
13 #include < cstdio >
14 #include < string .h >
15 #include < vector >
16 #include < math.h >
17 #define inf 0x3fffffff
18 using namespace std;
19 const int N = 305 ;
20 const int M = 4000 ;
21 int map[N][N];
22 vector < int > g[ 65 ];
23 int out [N];
24 int beg[ 65 ], end[ 65 ];
25 int U[M], D[M], R[M], L[M], rs[N];
26 int size[N], head, row[M], col[M];
27 int n, m, k;
28 int nodecnt, maxdepth;
29 struct point
30 {
31 int x,y;
32 point( int xx = 0 , int yy = 0 ):x(xx),y(yy){}
33 };
34 point shu[ 65 ];
35 void read() {
36 int i, j;
37 for (i = 0 ; i <= n; i ++ ) {
38 g[i].clear();
39 g[i].push_back(i);
40 }
41 for (i = 0 ; i < m; i ++ ) {
42 int a, b;
43 scanf( " %d%d " , & a, & b);
44 a -- , b -- ;
45 g[a].push_back(b);
46 g[b].push_back(a);
47 }
48 for (i = 0 ; i < n; i ++ ) scanf( " %d%d " , beg + i, end + i);
49 }
50
51 void init( int m) {
52 memset(size, 0 , sizeof (size));
53 memset(col, - 1 , sizeof (col));
54 nodecnt = m + 1 ;
55 for ( int i = 0 ; i <= m; i ++ ) {
56 L[i] = (i - 1 );
57 R[i] = (i + 1 );
58 col[i] = i;
59 D[i] = U[i] = i;
60 }
61 L[ 0 ] = m;
62 R[m] = 0 ;
63 size[ 0 ] = INT_MAX;
64 }
65 int ans[N];
66 int len;
67 bool yes;
68
69 inline void remove( int id) {
70 int i, j;
71 R[ L[id] ] = R[id];
72 L[ R[id] ] = L[id];
73 for (i = D[id]; i != id; i = D[i])
74 for (j = R[i]; j != i; j = R[j]) {
75 U[ D[j] ] = U[j];
76 D[ U[j] ] = D[j];
77 size[ col[j] ] -- ;
78 }
79 }
80
81 inline void resume( int id) {
82 int i, j;
83 for (i = U[id]; i != id; i = U[i])
84 for (j = L[i]; j != i; j = L[j]) {
85 size[ col[j] ] ++ ;
86 U[ D[j] ] = j;
87 D[ U[j] ] = j;
88 }
89 R[ L[id] ] = id;
90 L[ R[id] ] = id;
91 }
92
93 int ansL;
94
95 int output() {
96 memset( out , 0 , sizeof ( out ));
97 for ( int i = 0 ; i < ansL; i ++ ) {
98 out [ans[i]] = 1 ;
99 }
100 for ( int i = 0 ; i < n; i ++ ) {
101 int a, b;
102 a = b = 0 ;
103 for ( int j = 1 ; j <= k; j ++ ) {
104 if (j == 1 ) {
105 if ( out [i * k + j] == 1 ) a = j;
106 } else {
107 if ( out [i * k + j] == 1 && out [i * k + j - 1 ] == 0 )
108 {
109 if (a) return 0 ;
110 else a = j;
111 }
112 }
113 if (j == k) {
114 if ( out [i * k + j] == 1 ) b = j;
115 } else {
116 if ( out [i * k + j] == 1 && out [i * k + j + 1 ] == 0 )
117 {
118 if (b) return 0 ;
119 else b = j;
120 }
121 }
122 }
123 shu[i] = point(a,b);
124 }
125 return 1 ;
126 }
127
128 void dfs1( int num) {
129 if (R[ 0 ] == 0 ) {
130 ansL = num;
131 yes = output();
132 if (yes)
133 {
134 for ( int i = 0 ;i < n;i ++ ) printf( " %d %d\n " ,shu[i].x,shu[i].y);
135 puts( "" );
136 }
137 return ;
138 }
139 int i, j, id = 0 , min = inf;
140 for (i = R[ 0 ]; i != 0 ; i = R[i])
141 if (size[i] < min) {
142 min = size[i];
143 id = i;
144 }
145 remove(id);
146 for (i = D[id]; i != id; i = D[i]) {
147 ans[num] = row[i];
148 for (j = R[i]; j != i; j = R[j])
149 remove(col[j]);
150 dfs1(num + 1 );
151 if (yes) return ;
152 for (j = L[i]; j != i; j = L[j])
153 resume(col[j]);
154 }
155 resume(id);
156 }
157
158 inline void insert( int i, int * tt, int c) {
159 for ( int j = 0 ; j < c; j ++ , nodecnt ++ ) {
160 int x = tt[j];
161 row[nodecnt] = i;
162 col[nodecnt] = x;
163 size[x] ++ ;
164 U[nodecnt] = x;
165 D[nodecnt] = D[x];
166 U[D[x]] = nodecnt;
167 D[x] = nodecnt;
168 if (j == 0 ) L[nodecnt] = R[nodecnt] = nodecnt;
169 else {
170 L[nodecnt] = nodecnt - 1 ;
171 R[nodecnt] = nodecnt - j;
172 R[nodecnt - 1 ] = nodecnt;
173 L[nodecnt - j] = nodecnt;
174 }
175 }
176 }
177
178 void build() {
179 init(n * k);
180 int tt[ 305 ], c = 0 ;
181 int t = n * k + 1 ;
182 for ( int i = 1 ; i < t; i ++ ) {
183 c = 0 ;
184 for ( int j = 1 ; j < t; j ++ )
185 if (map[i][j] == 1 ) tt[c ++ ] = j;
186 insert(i, tt, c);
187 }
188 }
189
190 void solve() {
191 memset(map, 0 , sizeof (map));
192 for ( int i = 0 ; i < n; i ++ ) {
193 for ( int j = beg[i]; j <= end[i]; j ++ ) {
194 for ( int a = 0 ; a < g[i].size(); a ++ ) {
195 map[i * k + j][g[i][a] * k + j] = 1 ;
196 }
197 }
198 }
199 memset( out , 0 , sizeof ( out ));
200 int flag = 0 ;
201 while (flag < 1 ) {
202 build();
203 ansL = inf;
204 yes = false ;
205 dfs1( 0 );
206 if (yes == false ) {
207 puts( " No solution\n " );
208 return ;
209 }
210 flag ++ ;
211 }
212 }
213
214 int main() {
215 // freopen("in.txt", "r", stdin);
216 // freopen("out.txt", "w", stdout);
217 while (scanf( " %d%d%d " , & n, & m, & k) != EOF) {
218 read();
219 solve();
220 }
221 return 0 ;
222 }
添加几组测试数据:
3
3
5
1 2
2 3
3 1
1 5
1 5
1 5
4 4 5
1 2
2 3
3 4
4 1
1 5
1 5
1 5
1 5
2 1 5
1 2
1 2
3 5
6 5 5
1 2
1 3
1 4
1 5
1 6
1 5
3 5
2 3
1 3
2 3
3 4
6 9 5
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
1 5
3 4
1 2
2 3
1 3
3 5
1 2
2 3
3 1
1 5
1 5
1 5
4 4 5
1 2
2 3
3 4
4 1
1 5
1 5
1 5
1 5
2 1 5
1 2
1 2
3 5
6 5 5
1 2
1 3
1 4
1 5
1 6
1 5
3 5
2 3
1 3
2 3
3 4
6 9 5
1 2
1 3
1 4
1 5
1 6
2 3
2 4
2 5
2 6
1 5
3 4
1 2
2 3
1 3
3 5
输出: (spj题目,输出不唯一).
0
0
0 0
1 5
No solution
1 2
3 5
1 5
0 0
0 0
0 0
0 0
0 0
1 5
0 0
0 0
0 0
0 0
0 0
0 0
1 5
No solution
1 2
3 5
1 5
0 0
0 0
0 0
0 0
0 0
1 5
0 0
0 0
0 0
0 0
0 0