晓天动漫

Coding yy life……

Herbin 1004 Power Stations

第35届ACM/ICPC亚洲区预选赛哈尔滨赛区的 1004 题,Power Stations。

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, 0sizeof (size));
 53     memset(col, -1sizeof (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(out0sizeof (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, 0sizeof (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(out0sizeof (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

输出:  (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


posted on 2010-09-29 15:27 晓天_xiaotian 阅读(219) 评论(0)  编辑 收藏 引用 所属分类: 搜索专版


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年9月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

常用链接

留言簿

随笔分类

随笔档案

相册

收藏夹

ACM Online Judge

搜索

最新评论

阅读排行榜

评论排行榜