Herbin 1004 Power Stations

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,  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

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


你可能感兴趣的:(Herbin 1004 Power Stations)