[kuangbin带你飞]专题三 Dancing Links

Dancing Links 是一种数据结构,用于精确覆盖。详情去下面链接学;感谢大牛总结。

DancingLinks关键在于:

第一步,矩阵建立,行与列的确定,插入元素。这里行表示所有可能发生的情况,相当于搜索的每一个决定,答案就是某些行的集合。列就是答案完成的条件,只有满足所有列才有答案。

以下面题目九宫格来举例子,行是9*9*9,这里就是枚举了九宫格所有格子放1~9的所有情况,相当于所有可能放生的决策;列就是:这个行所带来的影响,即每个行之间的冲突,举例:一个行会带来4个列,1.该格子是否有数字填充?2.该格子的列是否有数字k?3.该格子 的行是否有数字K?4.该格子的九宫格里是否有数字K?

第二步:(不可重复覆盖)通过选一个列中一个行,来删除矩阵。为了避免答案的冲突,把所有相关的元素都删除掉。回复则按照相反顺序回复。

 

学习资料: http://www.cnblogs.com/grenet/p/3145800.html http://blog.csdn.net/mu399/article/details/7627862


 F - SudokuPOJ - 3074 

题意:就是给你一个随机的九宫格,问你答案是多少?

算法:Dancing Links

思路:Dancing Links的行和列都是从1开始的;这里除了本身给出的格子有数字外,其他格子都要从1~9选填,所以行最大就是N*N*N;列:每一行都有4个列,此格子有数字、此格子所在行有数字K、此格子所在列有数字K、此格子九宫格有数字K

代码:其实抄的摸版,摸版刚好做这题。

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int INF = 0x3f3f3f3f;
 13 const int N = 9;
 14 const int MaxN = N*N*N + 10;
 15 const int MaxM = N*N*4 + 10;
 16 const int maxnode = MaxN*4 + MaxM + 10;
 17 char g[MaxN];
 18 struct DLX{
 19     int n,m,size;
 20     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 21     int H[MaxN],S[MaxM];
 22     int ansd,ans[MaxN];
 23     void init(int _n,int _m){
 24         n = _n , m = _m;
 25         for(int i = 0;i <= m;i++){
 26             S[i] = 0;
 27             U[i] = D[i] = i;
 28             L[i]  = i-1;
 29             R[i] = i+1;
 30         }
 31         R[m] = 0, L[0] = m, size = m;
 32         for(int i = 1;i <= n; i++) H[i] = -1;
 33     }
 34     void Link(int r,int c){
 35         ++S[Col[++size]=c];
 36         Row[size] = r;
 37         D[size] = D[c];
 38         U[D[c]] = size;
 39         U[size] = c;
 40         D[c] = size;
 41         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 42         else{
 43             R[size] = R[H[r]];
 44             L[R[H[r]]] = size;
 45             L[size] = H[r];
 46             R[H[r]] = size;
 47         }
 48     }
 49     void remove(int c){
 50         L[R[c]] = L[c] , R[L[c]] = R[c];
 51         for(int i = D[c];i != c;i = D[i])
 52             for(int j = R[i];j != i;j = R[j]){
 53                 U[D[j]] = U[j] , D[U[j]] = D[j] , --S[Col[j]];
 54         }
 55     }
 56     void resume(int c){
 57         for(int i = U[c];i != c;i = U[i])
 58             for(int j = L[i];j != i;j = L[j]){
 59                 ++S[Col[U[D[j]]=D[U[j]]=j]];
 60         }
 61         L[R[c]] = R[L[c]] = c;
 62     }
 63     bool Dance(int d){
 64         if(R[0] == 0){
 65             for(int i = 0;i < d;i++) g[(ans[i]-1)/9] = (ans[i]-1)%9 + '1';//行和列都是从1开始的
 66             for(int i = 0;i < N*N;i++) printf("%c",g[i]);printf("\n");
 67             return true;
 68         }
 69         int c = R[0];
 70         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 71         remove(c);
 72         for(int i = D[c];i != c;i = D[i]){
 73             ans[d] = Row[i];
 74             for(int j = R[i];j != i;j = R[j]) remove(Col[j]);
 75             if(Dance(d+1)) return true;
 76             for(int j = L[i];j != i;j = L[j]) resume(Col[j]);
 77         }
 78         resume(c);
 79         return false;
 80     }
 81 };
 82 void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k){
 83     r = (i*N+j)*N + k;//N*N*N 循环到这里K,所以就是9宫格都是选K填
 84     c1 = i*N+j+1;//从1开始的,0只是个头,这个格子选填K
 85     c2 = N*N + i*N + k;//前i行都完成,到这一行的K
 86     c3 = N*N*2 + j*N + k;//前j列都完成,到这一列的K
 87     c4 = N*N*3 + ((i/3)*3+j/3)*N + k;//前面九宫格都选完了,到这个九宫格选填K
 88 }
 89 DLX dlx;
 90 int main()
 91 {
 92     while(scanf("%s",g) == 1){
 93         if(strcmp(g,"end") == 0) break;
 94         dlx.init(N*N*N,N*N*4);//行:N*N从(1~9)选填,列:每个格子都会有4个列,1:此格子有数字了2:此行有K了3:此列有K了4:这个格子的九宫格有K了
 95         int r,c1,c2,c3,c4;
 96         for(int i = 0;i < N;i++)
 97             for(int j = 0;j < N;j++)
 98                 for(int k = 1;k <= N;k++)
 99                     if(g[i*N+j] == '.' || g[i*N+j] == '0' + k){//此格子为空或者已经有K了
100                         place(r,c1,c2,c3,c4,i,j,k);
101                         dlx.Link(r,c1) , dlx.Link(r,c2) ,  dlx.Link(r,c3) , dlx.Link(r,c4);
102                     }
103         dlx.Dance(0);
104     }
105     return 0;
106 }
View Code


 D - 神龙的难题FZU - 1686

题意:给你一个n*m的01地图,1表示敌人,然后给你一个n1,m1,表示龙的攻击范围,问龙至少要攻击多少次才能消灭所有敌人?

算法:Dancing Links(可覆盖)

思路:行:n*m表示所有攻击选择,列:sz 敌人数。一个攻击能消灭多少敌人,然后消灭所有敌人才是答案。因为这里行选择是不冲突的,因为你攻击了一个格子之后消灭了敌人,但是第二次还是可以去一样敌人格子去攻击,只是敌人会减少,这里就是行对应的列可以重复的情况,可覆盖情况,所以删矩阵的时候,只是删列,不删行。

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int MaxN = 15*15 + 10;
 13 const int MaxM = 15*15 + 10;
 14 const int maxnode = MaxN*MaxM;
 15 const int INF = 0x3f3f3f3f;
 16 
 17 struct DLX{
 18     int n,m,size;
 19     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 20     int H[MaxN],S[MaxM];
 21     int ansd;
 22     void init(int _n,int _m){
 23         n = _n , m = _m;
 24         for(int i = 0;i <= m;i++){
 25             S[i] = 0;
 26             U[i] = D[i] = i;
 27             L[i]  = i-1;
 28             R[i] = i+1;
 29         }
 30         R[m] = 0, L[0] = m, size = m;
 31         for(int i = 1;i <= n; i++) H[i] = -1;
 32     }
 33     void Link(int r,int c){
 34         ++S[Col[++size]=c];
 35         Row[size] = r;
 36         D[size] = D[c];
 37         U[D[c]] = size;
 38         U[size] = c;
 39         D[c] = size;
 40         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 41         else{
 42             R[size] = R[H[r]];
 43             L[R[H[r]]] = size;
 44             L[size] = H[r];
 45             R[H[r]] = size;
 46         }
 47     }
 48     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
 49     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
 50     bool v[MaxM];
 51     int f(){
 52         int ret = 0;
 53         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
 54         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
 55             ret++;
 56             v[c]=false;
 57             for(int i = D[c];i != c;i = D[i])
 58                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
 59         }
 60         return ret;
 61     }
 62     void Dance(int d){
 63         if(d + f() >= ansd) return ;
 64         if(R[0] == 0){
 65             if(d < ansd) ansd = d;
 66             return ;
 67         }
 68         int c = R[0];
 69         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 70         for(int i = D[c];i != c;i = D[i]){
 71             remove(i);
 72             for(int j = R[i];j != i;j = R[j]) remove(j);
 73             Dance(d+1);
 74             for(int j = L[i];j != i;j = L[j]) resume(j);
 75             resume(i);
 76         }
 77     }
 78 };
 79 DLX g;
 80 int a[20][20] , id[20][20];
 81 int main()
 82 {
 83     int n,m;
 84     while(scanf("%d%d",&n,&m) == 2){
 85         int sz = 0;
 86         memset(id,0,sizeof id);
 87         for(int i = 0;i < n;i++)
 88             for(int j = 0;j < m;j++){
 89                 scanf("%d",&a[i][j]);
 90                 if(a[i][j] == 1) id[i][j] = (++sz);
 91         }
 92         g.init(n*m,sz);
 93         sz = 1;
 94         int n1,m1;
 95         scanf("%d%d",&n1,&m1);
 96         for(int i = 0;i < n;i++)
 97             for(int j = 0;j < m;j++){
 98                 for(int x=0;x<n1&&i+x<n;x++)
 99                     for(int y=0;y<m1&&j+y<m;y++)
100                     if(id[i+x][j+y]) g.Link(sz,id[i+x][j+y]);
101                 sz++;
102         }
103         g.ansd = INF;
104         g.Dance(0);
105         printf("%d\n",g.ansd);
106     }
107     return 0;
108 }
View Code


 SudokuZOJ - 3122 

题意:给你一个16*16的16宫格,A~P,玩法和九宫格一样

算法:DancingLinks

思路:和 F - SudokuPOJ - 3074 一样;我甚至代码也没改多少,就改了一些参数就过了

易错点:就是输出需要注意一下,输出之间要有个空格,但是最后不能有

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int INF = 0x3f3f3f3f;
 13 const int N = 16;
 14 const int MaxN = N*N*N + 10;
 15 const int MaxM = N*N*4 + 10;
 16 const int maxnode = MaxN*4 + MaxM + 10;
 17 char g[16*16+1];
 18 
 19 struct DLX{
 20     int n,m,size;
 21     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 22     int H[MaxN],S[MaxM];
 23     int ans[MaxN];
 24     void init(int _n,int _m){
 25         n = _n , m = _m;
 26         for(int i = 0;i <= m;i++){
 27             S[i] = 0;
 28             U[i] = D[i] = i;
 29             L[i]  = i-1;
 30             R[i] = i+1;
 31         }
 32         R[m] = 0, L[0] = m, size = m;
 33         for(int i = 1;i <= n; i++) H[i] = -1;
 34     }
 35     void Link(int r,int c){
 36         ++S[Col[++size]=c];
 37         Row[size] = r;
 38         D[size] = D[c];
 39         U[D[c]] = size;
 40         U[size] = c;
 41         D[c] = size;
 42         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 43         else{
 44             R[size] = R[H[r]];
 45             L[R[H[r]]] = size;
 46             L[size] = H[r];
 47             R[H[r]] = size;
 48         }
 49     }
 50     void remove(int c){
 51         L[R[c]] = L[c] , R[L[c]] = R[c];
 52         for(int i = D[c];i != c;i = D[i])
 53             for(int j = R[i];j != i;j = R[j]){
 54                 U[D[j]] = U[j] , D[U[j]] = D[j] , --S[Col[j]];
 55         }
 56     }
 57     void resume(int c){
 58         for(int i = U[c];i != c;i = U[i])
 59             for(int j = L[i];j != i;j = L[j]){
 60                 ++S[Col[U[D[j]]=D[U[j]]=j]];
 61         }
 62         L[R[c]] = R[L[c]] = c;
 63     }
 64     bool Dance(int d){
 65         if(R[0] == 0){
 66             for(int i = 0;i < d;i++) g[(ans[i]-1)/16] = (ans[i]-1)%16 + 'A';
 67             int num = 0;
 68             for(int i=0;i<N;i++){for(int j=0;j<N;j++) printf("%c",g[num++]);printf("\n");}
 69             return true;
 70         }
 71         int c = R[0];
 72         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 73         remove(c);
 74         for(int i = D[c];i != c;i = D[i]){
 75             ans[d] = Row[i];
 76             for(int j = R[i];j != i;j = R[j]) remove(Col[j]);
 77             if(Dance(d+1)) return true;
 78             for(int j = L[i];j != i;j = L[j]) resume(Col[j]);
 79         }
 80         resume(c);
 81         return false;
 82     }
 83 };
 84 void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k){
 85     r = (i*N+j)*N + k;
 86     c1 = i*N+j+1;
 87     c2 = N*N + i*N + k;
 88     c3 = N*N*2 + j*N + k;
 89     c4 = N*N*3 + ((i/4)*4+j/4)*N + k;
 90 }
 91 DLX dlx;
 92 int main()
 93 {
 94     int ca = 0;
 95     while(true){
 96         char ch;if((ch=getchar())==EOF) return 0;
 97         while(ch==' '||ch=='\n'){if((ch=getchar())==EOF) return 0;}
 98         if(ca++) printf("\n");
 99         g[0] = ch;
100         for(int i=1;i<N*N;i++){
101             ch=getchar();while(ch==' '||ch=='\n') ch=getchar();
102             g[i] = ch;
103         }
104 
105         dlx.init(N*N*N,N*N*4);
106         int r,c1,c2,c3,c4;
107         for(int i = 0;i < N;i++)
108             for(int j = 0;j < N;j++)
109                 for(int k = 1;k <= N;k++)
110                     if(g[i*N+j] == '-' || g[i*N+j] == 'A' + k - 1){
111                         place(r,c1,c2,c3,c4,i,j,k);
112                         dlx.Link(r,c1) , dlx.Link(r,c2) ,  dlx.Link(r,c3) , dlx.Link(r,c4);
113                     }
114         dlx.Dance(0);
115     }
116     return 0;
117 }
View Code


 A - Exact coverHUST - 1017

题意:就是经典问题:给你一堆01行组成的01矩阵,问你找出那些行可以覆盖所有列的1。任意答案即可。

算法:Dancing Links

思路:经典问题经典解决办法(这题的oj提交不了,所以我下面代码没提交过,不过应该没什么大问题)

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <map>
#include <math.h>

using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 16;
const int MaxN = 1000 + 10;
const int MaxM = 1000 + 10;
const int maxnode = MaxN*MaxM + 10;

struct DLX{
    int n,m,size;
    int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
    int H[MaxN],S[MaxM];
    int ans[MaxN];
    void init(int _n,int _m){
        n = _n , m = _m;
        for(int i = 0;i <= m;i++){
            S[i] = 0;
            U[i] = D[i] = i;
            L[i]  = i-1;
            R[i] = i+1;
        }
        R[m] = 0, L[0] = m, size = m;
        for(int i = 1;i <= n; i++) H[i] = -1;
    }
    void Link(int r,int c){
        ++S[Col[++size]=c];
        Row[size] = r;
        D[size] = D[c];
        U[D[c]] = size;
        U[size] = c;
        D[c] = size;
        if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
        else{
            R[size] = R[H[r]];
            L[R[H[r]]] = size;
            L[size] = H[r];
            R[H[r]] = size;
        }
    }
    void remove(int c){
        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]];
        }
    }
    void resume(int c){
        for(int i = U[c];i != c;i = U[i])
            for(int j = L[i];j != i;j = L[j]){
                ++S[Col[U[D[j]]=D[U[j]]=j]];
        }
        L[R[c]] = R[L[c]] = c;
    }
    bool Dance(int d){
        if(R[0] == 0){
            cout<<d;
            for(int i = 0;i < d;i++) cout<<" "<<ans[i];cout<<endl;
            return true;
        }
        int c = R[0];
        for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
        remove(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]) remove(Col[j]);
            if(Dance(d+1)) return true;
            for(int j = L[i];j != i;j = L[j]) resume(Col[j]);
        }
        resume(c);
        return false;
    }
};
DLX dlx;
int main()
{
    int n,m;
    while(cin>>n>>m){
        dlx.init(n,m);
        for(int i=1;i<=n;i++){
            int a;cin>>a;
            for(int j=0;j<a;j++){
                int b;cin>>b;
                dlx.Link(i,b);
            }
        }
        dlx.Dance(0);
    }
    return 0;
}
View Code


B - Treasure MapZOJ - 3209

题意:有一副(0,0)到(n,m)坐标大的地图,给你很多地图碎片,问那些地图碎片可以组合成一幅完整的地图,要求数量最少并且这些地图碎片不能重叠?

算法:dancinglinks

思路:一开始是打算,用点做列的,发现地图连接的时候边上的点会重叠;后面想了一下,改用坐标上的方格做列,这样地图碎片之间就不会重叠。

 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <cstdio>
 7 #include <map>
 8 #include <math.h>
 9 
10 using namespace std;
11 
12 const int INF = 0x3f3f3f3f;
13 const int N = 31;
14 const int MaxN = 961 + 10;
15 const int MaxM = 500 + 10;
16 const int maxnode = MaxN*MaxM + 10;
17 
18 struct DLX{
19     int n,m,size;
20     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
21     int H[MaxN],S[MaxM];
22     int ansd,ans[MaxM];
23     void init(int _n,int _m){
24         n = _n , m = _m;
25         for(int i = 0;i <= m;i++){
26             S[i] = 0;
27             U[i] = D[i] = i;
28             L[i]  = i-1;
29             R[i] = i+1;
30         }
31         R[m] = 0, L[0] = m, size = m;
32         for(int i = 1;i <= n; i++) H[i] = -1;
33     }
34     void Link(int r,int c){
35         ++S[Col[++size]=c];
36         Row[size] = r;
37         D[size] = D[c];
38         U[D[c]] = size;
39         U[size] = c;
40         D[c] = size;
41         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
42         else{
43             R[size] = R[H[r]];
44             L[R[H[r]]] = size;
45             L[size] = H[r];
46             R[H[r]] = size;
47         }
48     }
49     void remove(int c){
50         L[R[c]] = L[c] , R[L[c]] = R[c];
51         for(int i = D[c];i != c;i = D[i])
52             for(int j = R[i];j != i;j = R[j]){
53                 U[D[j]] = U[j] , D[U[j]] = D[j] , --S[Col[j]];
54         }
55     }
56     void resume(int c){
57         for(int i = U[c];i != c;i = U[i])
58             for(int j = L[i];j != i;j = L[j]){
59                 ++S[Col[U[D[j]]=D[U[j]]=j]];
60         }
61         L[R[c]] = R[L[c]] = c;
62     }
63     bool Dance(int d){
64         if(R[0] == 0){
65             if(ansd==-1) ansd = d;
66             else ansd = min(ansd,d);
67         }
68         int c = R[0];
69         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
70         remove(c);
71         for(int i = D[c];i != c;i = D[i]){
72             ans[d] = Row[i];
73             for(int j = R[i];j != i;j = R[j]) remove(Col[j]);
74             if(Dance(d+1)) return true;
75             for(int j = L[i];j != i;j = L[j]) resume(Col[j]);
76         }
77         resume(c);
78         return false;
79     }
80 };
81 DLX dlx;
82 int main()
83 {
84     int _;cin>>_;
85     while(_--){
86         int n,m,k;cin>>n>>m>>k;
87         dlx.init(k,n*m);
88         for(int z=1;z<=k;z++){
89             int a,b,c,d;cin>>a>>b>>c>>d;
90             for(int j=b;j<d;j++)
91                 for(int i=a;i<c;i++)
92                     dlx.Link(z,j*n+i+1);
93         }
94         dlx.ansd=-1;
95         dlx.Dance(0);
96         cout<<dlx.ansd<<endl;
97     }
98     return 0;
99 }
View Code


 RadarHDU - 2295 

题意:给你N个城市,M个雷达,K个雷达操作员;每个雷达的扫描半径一样;问你在最多K个雷达下,设置最小半径为多少可以覆盖所有城市。

算法:DancingLinks

思路:这里行是雷达,列是城市;存储每个雷达到城市的距离,然后用一个set记录所有距离,从最小距离设定为扫描半径R开始,按照这个R来Link雷达与城市,如果dance不成功;就逐步扩大R;

易错点:这里Dancing,需要一个预估函数来剪枝,不然会超时

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 #include <iomanip>
 10 #include <set>
 11 
 12 using namespace std;
 13 
 14 const int INF = 0x3f3f3f3f;
 15 const int N = 50;
 16 const int MaxN = N + 10;
 17 const int MaxM = N + 10;
 18 const int maxnode = MaxN*MaxM + 10;
 19 
 20 int n,m,k;
 21 struct DLX{
 22     int n,m,size;
 23     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 24     int H[MaxN],S[MaxM];
 25     int ans[MaxN];
 26     void init(int _n,int _m){
 27         n = _n , m = _m;
 28         for(int i = 0;i <= m;i++){
 29             S[i] = 0;
 30             U[i] = D[i] = i;
 31             L[i]  = i-1;
 32             R[i] = i+1;
 33         }
 34         R[m] = 0, L[0] = m, size = m;
 35         for(int i = 1;i <= n; i++) H[i] = -1;
 36     }
 37     void Link(int r,int c){
 38         ++S[Col[++size]=c];
 39         Row[size] = r;
 40         D[size] = D[c];
 41         U[D[c]] = size;
 42         U[size] = c;
 43         D[c] = size;
 44         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 45         else{
 46             R[size] = R[H[r]];
 47             L[R[H[r]]] = size;
 48             L[size] = H[r];
 49             R[H[r]] = size;
 50         }
 51     }
 52     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
 53     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
 54     bool checkout(){
 55         for(int i = R[0];i != 0;i = R[i]) if(S[i]==0) return false;
 56         return true;
 57     }
 58     bool v[MaxM];
 59     int f(){
 60         int ret = 0;
 61         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
 62         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
 63             ret++;
 64             v[c]=false;
 65             for(int i = D[c];i != c;i = D[i])
 66                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
 67         }
 68         return ret;
 69     }
 70     bool Dance(int d){
 71         if(d+f()>k) return false;
 72         if(R[0] == 0){
 73             if(d<=k) return true;
 74             return false;
 75         }
 76         int c = R[0];
 77         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 78         for(int i = D[c];i != c;i = D[i]){
 79             remove(i);
 80             for(int j = R[i];j != i;j = R[j]) remove(j);
 81             if(Dance(d+1)) return true;
 82             for(int j = L[i];j != i;j = L[j]) resume(j);
 83             resume(i);
 84         }
 85         return false;
 86     }
 87 };
 88 DLX dlx;
 89 
 90 struct  radarTocity{
 91     double R,city;
 92     radarTocity(double a,int b):R(a),city(b) {}
 93     bool operator < (const radarTocity &a){
 94         return R<a.R;
 95     }
 96 };
 97 vector<radarTocity> radar[MaxN];
 98 int cityX[MaxM],cityY[MaxM];
 99 int radarNum[MaxN];
100 set<double> R;
101 
102 void LFL(double r){
103     for(int i=1;i<=m;i++){
104         for(int j=radarNum[i];j<radar[i].size();j++){
105             if(radar[i][j].R>r) break;
106             dlx.Link(i,radar[i][j].city);
107             radarNum[i]++;
108         }
109     }
110 }
111 
112 int main()
113 {
114     int _;cin>>_;
115     while(_--){
116         cin>>n>>m>>k;
117         R.clear();
118         for(int i=1;i<=n;i++) cin>>cityX[i]>>cityY[i];
119         for(int i=1;i<=m;i++){
120             radar[i].clear();
121             int x,y;cin>>x>>y;
122             radarNum[i] = 0;
123             for(int j=1;j<=n;j++){
124                 int a = cityX[j] - x, b = cityY[j] - y;
125                 double r = a*a+b*b;R.insert(r);
126                 radar[i].push_back(radarTocity(r,j));
127             }
128             sort(radar[i].begin(),radar[i].end());
129         }
130         dlx.init(m,n);
131         set<double>::iterator it;
132         for(it = R.begin();it != R.end();it++){
133             double r = *it;
134             LFL(r);
135             if(!dlx.checkout()) continue;
136            if(dlx. Dance(0)){
137                 cout<<fixed<<setprecision(6)<<sqrt(r)<<endl;
138                 break;
139             }
140         }
141     }
142     return 0;
143 }
View Code


 Square DestroyerPOJ - 1084 

题意:给你一个数字n,表示n*n的矩阵,这个矩阵由2n*(n+1)根火柴组成,编号如题目一样从左到右从上到下;然后给你一个数字K,然后后面跟着K个数,表示抽取这K根编号的火柴;问你至少还要取走多少根火柴才使你的矩阵里面没有可以由火柴组成的正方形?

算法:预处理+DancingLinks

思路:行是火柴,列是所有可能的正方形。因为一根火柴可能组成多个正方形,所以这里用可覆盖;n是小于等于5的自然数,所以当n=0,答案恒等于0;当n=1,如果K=0,答案等于1,否则等于0;

   当n=2开始,就要去组成DancingLink矩阵了...我比较笨,都是一个个手动码上去的。(这里看了别人的代码,才发现有规律,md,这都有规律,第一个发现真的大牛,反正如果比赛的话,说实话我还是会一个个码,毕竟我比较笨,动手能力强点)

易错点:第一次尝试:我这里就是再循环里面,进行Link,手动一个个匹配,然后再输入K个数,一个个除去;然后TLE了

    第二次尝试:我把Link放在了外面,一开始就预处理,dlx2、dlx3、dlx4、dlx5所有矩阵,然后每次除去K个火柴,结束时还原;还是TLE了。

    第三次尝试:这个我是看了别人代码做的,就是将每次去除的K个火柴,所可能的列都记录,然后再init之后对这些列进行隐藏,然后在后续Link的时候,主动避开这些列。然后就AC了。(这里的数组都要开大一点,不然会Runtimeerror)

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int INF = 0x3f3f3f3f;
 13 const int MaxN = 60 + 10;
 14 const int MaxM = 55 + 10;
 15 const int maxnode = MaxN*MaxM + 10;
 16 
 17 struct DLX{
 18     int n,m,size;
 19     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 20     int H[MaxN],S[MaxM];
 21     int ansd;
 22     void init(int _n,int _m){
 23         n = _n , m = _m;
 24         for(int i = 0;i <= m;i++){
 25             S[i] = 0;
 26             U[i] = D[i] = i;
 27             L[i]  = i-1;
 28             R[i] = i+1;
 29         }
 30         R[m] = 0, L[0] = m, size = m;
 31         for(int i = 1;i <= n; i++) H[i] = -1;
 32     }
 33     void Link(int r,int c){
 34         ++S[Col[++size]=c];
 35         Row[size] = r;
 36         D[size] = D[c];
 37         U[D[c]] = size;
 38         U[size] = c;
 39         D[c] = size;
 40         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 41         else{
 42             R[size] = R[H[r]];
 43             L[R[H[r]]] = size;
 44             L[size] = H[r];
 45             R[H[r]] = size;
 46         }
 47     }
 48     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
 49     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
 50     bool v[MaxM];
 51     int f(){
 52         int ret = 0;
 53         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
 54         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
 55             ret++;
 56             v[c]=false;
 57             for(int i = D[c];i != c;i = D[i])
 58                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
 59         }
 60         return ret;
 61     }
 62     void Dance(int d){
 63         if(d + f() >= ansd) return ;
 64         if(R[0] == 0){
 65             if(d < ansd) ansd = d;
 66             return ;
 67         }
 68         int c = R[0];
 69         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 70         for(int i = D[c];i != c;i = D[i]){
 71             remove(i);
 72             for(int j = R[i];j != i;j = R[j]) remove(j);
 73             Dance(d+1);
 74             for(int j = L[i];j != i;j = L[j]) resume(j);
 75             resume(i);
 76         }
 77     }
 78     void removeC(int c){
 79         L[R[c]] = L[c];
 80         R[L[c]] = R[c];
 81     }
 82 };
 83 DLX dlx;
 84 vector<int> v2[13],v3[25],v4[41],v5[61];
 85 void init(){
 86     v2[1].push_back(1),v2[1].push_back(5);
 87     v2[2].push_back(2),v2[1].push_back(5);
 88     v2[3].push_back(1),v2[3].push_back(5);
 89     v2[4].push_back(1),v2[4].push_back(2);
 90     v2[5].push_back(2),v2[5].push_back(5);
 91     v2[6].push_back(1),v2[6].push_back(3);
 92     v2[7].push_back(2),v2[7].push_back(4);
 93     v2[8].push_back(3),v2[8].push_back(5);
 94     v2[9].push_back(3),v2[9].push_back(4);
 95     v2[10].push_back(4),v2[10].push_back(5);
 96     v2[11].push_back(3),v2[11].push_back(5);
 97     v2[12].push_back(4),v2[12].push_back(5);
 98 //--------------------------------------------------------------------------------
 99     v3[1].push_back(1);v3[1].push_back(10);v3[1].push_back(14);
100     v3[2].push_back(2);v3[2].push_back(10);v3[2].push_back(11);v3[2].push_back(14);
101     v3[3].push_back(3);v3[3].push_back(11);v3[3].push_back(14);
102     v3[4].push_back(1);v3[4].push_back(10);v3[4].push_back(14);
103     v3[5].push_back(1);v3[5].push_back(2);v3[5].push_back(11);
104     v3[6].push_back(2);v3[6].push_back(3);v3[6].push_back(10);
105     v3[7].push_back(3);v3[7].push_back(11);v3[7].push_back(14);
106     v3[8].push_back(1);v3[8].push_back(4);v3[8].push_back(12);
107     v3[9].push_back(2);v3[9].push_back(5);v3[9].push_back(12);v3[9].push_back(13);
108     v3[10].push_back(3);v3[10].push_back(6);v3[10].push_back(13);
109     v3[11].push_back(4); v3[11].push_back(10); v3[11].push_back(12); v3[11].push_back(14);
110     v3[12].push_back(4);v3[12].push_back(5);v3[12].push_back(11);v3[12].push_back(13);
111     v3[13].push_back(5);v3[13].push_back(6);v3[13].push_back(10);v3[13].push_back(12);
112     v3[14].push_back(6);v3[14].push_back(11);v3[14].push_back(13);v3[14].push_back(14);
113     v3[15].push_back(4);v3[15].push_back(7);v3[15].push_back(10);
114     v3[16].push_back(5);v3[16].push_back(8);v3[16].push_back(10);v3[16].push_back(11);
115     v3[17].push_back(6);v3[17].push_back(9);v3[17].push_back(11);
116     v3[18].push_back(7);v3[18].push_back(12);v3[18].push_back(14);
117     v3[19].push_back(7);v3[19].push_back(8);v3[19].push_back(13);
118     v3[20].push_back(8);v3[20].push_back(9);v3[20].push_back(12);
119     v3[21].push_back(9);v3[21].push_back(13);v3[21].push_back(14);
120     v3[22].push_back(7);v3[22].push_back(12);v3[22].push_back(14);
121     v3[23].push_back(8);v3[23].push_back(12);v3[23].push_back(13);v3[23].push_back(14);
122     v3[24].push_back(9);v3[24].push_back(13);v3[24].push_back(14);
123 //--------------------------------------------------------------------------------
124     v4[1].push_back(1);v4[5].push_back(1);v4[6].push_back(1);v4[10].push_back(1);
125     v4[2].push_back(2);v4[6].push_back(2);v4[7].push_back(2);v4[11].push_back(2);
126     v4[3].push_back(3);v4[7].push_back(3);v4[8].push_back(3);v4[12].push_back(3);
127     v4[4].push_back(4);v4[8].push_back(4);v4[9].push_back(4);v4[13].push_back(4);
128     v4[10].push_back(5);v4[14].push_back(5);v4[15].push_back(5);v4[19].push_back(5);
129     v4[11].push_back(6);v4[15].push_back(6);v4[16].push_back(6);v4[20].push_back(6);
130     v4[12].push_back(7);v4[16].push_back(7);v4[17].push_back(7);v4[21].push_back(7);
131     v4[13].push_back(8);v4[17].push_back(8);v4[18].push_back(8);v4[22].push_back(8);
132     v4[19].push_back(9);v4[23].push_back(9);v4[24].push_back(9);v4[28].push_back(9);
133     v4[20].push_back(10);v4[24].push_back(10);v4[25].push_back(10);v4[29].push_back(10);
134     v4[21].push_back(11);v4[25].push_back(11);v4[26].push_back(11);v4[30].push_back(11);
135     v4[22].push_back(12);v4[26].push_back(12);v4[27].push_back(12);v4[31].push_back(12);
136     v4[28].push_back(13);v4[32].push_back(13);v4[33].push_back(13);v4[37].push_back(13);
137     v4[29].push_back(14);v4[33].push_back(14);v4[34].push_back(14);v4[38].push_back(14);
138     v4[30].push_back(15);v4[34].push_back(15);v4[35].push_back(15);v4[39].push_back(15);
139     v4[31].push_back(16);v4[35].push_back(16);v4[36].push_back(16);v4[40].push_back(16);
140     v4[1].push_back(17);v4[3].push_back(19);v4[11].push_back(21);v4[19].push_back(23);v4[21].push_back(25);
141     v4[2].push_back(18);v4[10].push_back(20);v4[12].push_back(22);v4[20].push_back(24);
142     v4[2].push_back(17);v4[4].push_back(19);v4[12].push_back(21);v4[20].push_back(23);v4[22].push_back(25);
143     v4[3].push_back(18);v4[11].push_back(20);v4[13].push_back(22);v4[21].push_back(24);
144     v4[5].push_back(17);v4[7].push_back(19);v4[15].push_back(21);v4[23].push_back(23);v4[25].push_back(25);
145     v4[6].push_back(18);v4[14].push_back(20);v4[16].push_back(22);v4[24].push_back(24);
146     v4[7].push_back(17);v4[9].push_back(19);v4[17].push_back(21);v4[25].push_back(23);v4[27].push_back(25);
147     v4[8].push_back(18);v4[16].push_back(20);v4[18].push_back(22);v4[26].push_back(24);
148     v4[14].push_back(17);v4[16].push_back(19);v4[24].push_back(21);v4[32].push_back(23);v4[34].push_back(25);
149     v4[15].push_back(18);v4[23].push_back(20);v4[25].push_back(22);v4[33].push_back(24);
150     v4[16].push_back(17);v4[18].push_back(19);v4[26].push_back(21);v4[34].push_back(23);v4[36].push_back(25);
151     v4[17].push_back(18);v4[25].push_back(20);v4[27].push_back(22);v4[35].push_back(24);
152     v4[19].push_back(17);v4[21].push_back(19);v4[29].push_back(21);v4[37].push_back(23);v4[39].push_back(25);
153     v4[20].push_back(18);v4[28].push_back(20);v4[30].push_back(22);v4[38].push_back(24);
154     v4[20].push_back(17);v4[22].push_back(19);v4[30].push_back(21);v4[38].push_back(23);v4[40].push_back(25);
155     v4[21].push_back(18);v4[29].push_back(20);v4[31].push_back(22);v4[39].push_back(24);
156     v4[1].push_back(26);v4[2].push_back(27);v4[10].push_back(28);v4[11].push_back(29);
157     v4[2].push_back(26);v4[3].push_back(27);v4[11].push_back(28);v4[12].push_back(29);
158     v4[3].push_back(26);v4[4].push_back(27);v4[12].push_back(28);v4[13].push_back(29);
159     v4[5].push_back(26);v4[6].push_back(27);v4[14].push_back(28);v4[15].push_back(29);
160     v4[8].push_back(26);v4[9].push_back(27);v4[17].push_back(28);v4[18].push_back(29);
161     v4[14].push_back(26);v4[15].push_back(27);v4[23].push_back(28);v4[24].push_back(29);
162     v4[17].push_back(26);v4[18].push_back(27);v4[26].push_back(28);v4[27].push_back(29);
163     v4[23].push_back(26);v4[24].push_back(27);v4[32].push_back(28);v4[33].push_back(29);
164     v4[26].push_back(26);v4[27].push_back(27);v4[35].push_back(28);v4[36].push_back(29);
165     v4[28].push_back(26);v4[29].push_back(27);v4[37].push_back(28);v4[38].push_back(29);
166     v4[29].push_back(26);v4[30].push_back(27);v4[38].push_back(28);v4[39].push_back(29);
167     v4[30].push_back(26);v4[31].push_back(27);v4[39].push_back(28);v4[40].push_back(29);
168     v4[1].push_back(30);v4[2].push_back(30);v4[3].push_back(30);v4[4].push_back(30);v4[5].push_back(30);v4[9].push_back(30);v4[14].push_back(30);
169     v4[18].push_back(30);v4[23].push_back(30);v4[27].push_back(30);v4[32].push_back(30);v4[36].push_back(30);v4[37].push_back(30);v4[38].push_back(30);
170     v4[39].push_back(30);v4[40].push_back(30);
171 //-------------------------------------------------------------------------------------------------------------------
172     v5[1].push_back(1);v5[6].push_back(1);v5[7].push_back(1);v5[12].push_back(1);
173     v5[2].push_back(2);v5[7].push_back(2);v5[8].push_back(2);v5[13].push_back(2);
174     v5[3].push_back(3);v5[8].push_back(3);v5[9].push_back(3);v5[14].push_back(3);
175     v5[4].push_back(4);v5[9].push_back(4);v5[10].push_back(4);v5[15].push_back(4);
176     v5[5].push_back(5);v5[10].push_back(5);v5[11].push_back(5);v5[16].push_back(5);
177     v5[12].push_back(6);v5[17].push_back(6);v5[18].push_back(6);v5[23].push_back(6);
178     v5[13].push_back(7);v5[18].push_back(7);v5[19].push_back(7);v5[24].push_back(7);
179     v5[14].push_back(8);v5[19].push_back(8);v5[20].push_back(8);v5[25].push_back(8);
180     v5[15].push_back(9);v5[20].push_back(9);v5[21].push_back(9);v5[26].push_back(9);
181     v5[16].push_back(10);v5[21].push_back(10);v5[22].push_back(10);v5[27].push_back(10);
182     v5[23].push_back(11);v5[28].push_back(11);v5[29].push_back(11);v5[34].push_back(11);
183     v5[24].push_back(12);v5[29].push_back(12);v5[30].push_back(12);v5[35].push_back(12);
184     v5[25].push_back(13);v5[30].push_back(13);v5[31].push_back(13);v5[36].push_back(13);
185     v5[26].push_back(14);v5[31].push_back(14);v5[32].push_back(14);v5[37].push_back(14);
186     v5[27].push_back(15);v5[32].push_back(15);v5[33].push_back(15);v5[38].push_back(15);
187     v5[34].push_back(16);v5[39].push_back(16);v5[40].push_back(16);v5[45].push_back(16);
188     v5[35].push_back(17);v5[36].push_back(18);v5[37].push_back(19);v5[38].push_back(20);v5[45].push_back(21);v5[46].push_back(22);
189     v5[47].push_back(23);v5[48].push_back(24);v5[49].push_back(25);
190     v5[40].push_back(17);v5[41].push_back(18);v5[42].push_back(19);v5[43].push_back(20);v5[50].push_back(21);v5[51].push_back(22);
191     v5[52].push_back(23);v5[53].push_back(24);v5[54].push_back(25);
192     v5[41].push_back(17);v5[42].push_back(18);v5[43].push_back(19);v5[44].push_back(20);v5[51].push_back(21);v5[52].push_back(22);
193     v5[53].push_back(23);v5[54].push_back(24);v5[55].push_back(25);
194     v5[46].push_back(17);v5[47].push_back(18);v5[48].push_back(19);v5[49].push_back(20);v5[56].push_back(21);v5[57].push_back(22);
195     v5[58].push_back(23);v5[59].push_back(24);v5[60].push_back(25);
196     v5[1].push_back(26);v5[2].push_back(27);v5[3].push_back(28);v5[4].push_back(29);
197     v5[2].push_back(26);v5[3].push_back(27);v5[4].push_back(28);v5[5].push_back(29);
198     v5[6].push_back(26);v5[7].push_back(27);v5[8].push_back(28);v5[9].push_back(29);
199     v5[8].push_back(26);v5[9].push_back(27);v5[10].push_back(28);v5[11].push_back(29);
200     v5[17].push_back(26);v5[18].push_back(27);v5[19].push_back(28);v5[20].push_back(29);
201     v5[19].push_back(26);v5[20].push_back(27);v5[21].push_back(28);v5[22].push_back(29);
202     v5[23].push_back(26);v5[24].push_back(27);v5[25].push_back(28);v5[26].push_back(29);
203     v5[24].push_back(26);v5[25].push_back(27);v5[26].push_back(28);v5[27].push_back(29);
204     v5[12].push_back(30);v5[13].push_back(31);v5[14].push_back(32);v5[15].push_back(33);
205     v5[13].push_back(30);v5[14].push_back(31);v5[15].push_back(32);v5[16].push_back(33);
206     v5[17].push_back(30);v5[18].push_back(31);v5[19].push_back(32);v5[20].push_back(33);
207     v5[19].push_back(30);v5[20].push_back(31);v5[21].push_back(32);v5[22].push_back(33);
208     v5[28].push_back(30);v5[29].push_back(31);v5[30].push_back(32);v5[31].push_back(33);
209     v5[30].push_back(30);v5[31].push_back(31);v5[32].push_back(32);v5[33].push_back(33);
210     v5[34].push_back(30);v5[35].push_back(31);v5[36].push_back(32);v5[37].push_back(33);
211     v5[35].push_back(30);v5[36].push_back(31);v5[37].push_back(32);v5[38].push_back(33);
212     v5[23].push_back(34);v5[24].push_back(35);v5[25].push_back(36);v5[26].push_back(37);
213     v5[24].push_back(34);v5[25].push_back(35);v5[26].push_back(36);v5[27].push_back(37);
214     v5[28].push_back(34);v5[29].push_back(35);v5[30].push_back(36);v5[31].push_back(37);
215     v5[30].push_back(34);v5[31].push_back(35);v5[32].push_back(36);v5[33].push_back(37);
216     v5[39].push_back(34);v5[40].push_back(35);v5[41].push_back(36);v5[42].push_back(37);
217     v5[41].push_back(34);v5[42].push_back(35);v5[43].push_back(36);v5[44].push_back(37);
218     v5[45].push_back(34);v5[46].push_back(35);v5[47].push_back(36);v5[48].push_back(37);
219     v5[46].push_back(34);v5[47].push_back(35);v5[48].push_back(36);v5[49].push_back(37);
220     v5[34].push_back(38);v5[35].push_back(39);v5[36].push_back(40);v5[37].push_back(41);
221     v5[35].push_back(38);v5[36].push_back(39);v5[37].push_back(40);v5[38].push_back(41);
222     v5[39].push_back(38);v5[40].push_back(39);v5[41].push_back(40);v5[42].push_back(41);
223     v5[41].push_back(38);v5[42].push_back(39);v5[43].push_back(40);v5[44].push_back(41);
224     v5[50].push_back(38);v5[51].push_back(39);v5[52].push_back(40);v5[53].push_back(41);
225     v5[52].push_back(38);v5[53].push_back(39);v5[54].push_back(40);v5[55].push_back(41);
226     v5[56].push_back(38);v5[57].push_back(39);v5[58].push_back(40);v5[59].push_back(41);
227     v5[57].push_back(38);v5[58].push_back(39);v5[59].push_back(40);v5[60].push_back(41);
228     v5[1].push_back(42);v5[2].push_back(43);v5[3].push_back(44);
229     v5[2].push_back(42);v5[3].push_back(43);v5[4].push_back(44);
230     v5[3].push_back(42);v5[4].push_back(43);v5[5].push_back(44);
231     v5[6].push_back(42);v5[7].push_back(43);v5[8].push_back(44);
232     v5[9].push_back(42);v5[10].push_back(43);v5[11].push_back(44);
233     v5[17].push_back(42);v5[18].push_back(43);v5[19].push_back(44);
234     v5[20].push_back(42);v5[21].push_back(43);v5[22].push_back(44);
235     v5[28].push_back(42);v5[29].push_back(43);v5[30].push_back(44);
236     v5[31].push_back(42);v5[32].push_back(43);v5[33].push_back(44);
237     v5[34].push_back(42);v5[35].push_back(43);v5[36].push_back(44);
238     v5[35].push_back(42);v5[36].push_back(43);v5[37].push_back(44);
239     v5[36].push_back(42);v5[37].push_back(43);v5[38].push_back(44);
240     v5[12].push_back(45);v5[13].push_back(46);v5[14].push_back(47);
241     v5[13].push_back(45);v5[14].push_back(46);v5[15].push_back(47);
242     v5[14].push_back(45);v5[15].push_back(46);v5[16].push_back(47);
243     v5[17].push_back(45);v5[18].push_back(46);v5[19].push_back(47);
244     v5[20].push_back(45);v5[21].push_back(46);v5[22].push_back(47);
245     v5[28].push_back(45);v5[29].push_back(46);v5[30].push_back(47);
246     v5[31].push_back(45);v5[32].push_back(46);v5[33].push_back(47);
247     v5[39].push_back(45);v5[40].push_back(46);v5[41].push_back(47);
248     v5[42].push_back(45);v5[43].push_back(46);v5[44].push_back(47);
249     v5[45].push_back(45);v5[46].push_back(46);v5[47].push_back(47);
250     v5[46].push_back(45);v5[47].push_back(46);v5[48].push_back(47);
251     v5[47].push_back(45);v5[48].push_back(46);v5[49].push_back(47);
252     v5[23].push_back(48);v5[24].push_back(49);v5[25].push_back(50);
253     v5[24].push_back(48);v5[25].push_back(49);v5[26].push_back(50);
254     v5[25].push_back(48);v5[26].push_back(49);v5[27].push_back(50);
255     v5[28].push_back(48);v5[29].push_back(49);v5[30].push_back(50);
256     v5[31].push_back(48);v5[32].push_back(49);v5[33].push_back(50);
257     v5[39].push_back(48);v5[40].push_back(49);v5[41].push_back(50);
258     v5[42].push_back(48);v5[43].push_back(49);v5[44].push_back(50);
259     v5[50].push_back(48);v5[51].push_back(49);v5[52].push_back(50);
260     v5[53].push_back(48);v5[54].push_back(49);v5[55].push_back(50);
261     v5[56].push_back(48);v5[57].push_back(49);v5[58].push_back(50);
262     v5[57].push_back(48);v5[58].push_back(49);v5[59].push_back(50);
263     v5[58].push_back(48);v5[59].push_back(49);v5[60].push_back(50);
264     v5[1].push_back(51);v5[2].push_back(52);v5[12].push_back(53);v5[13].push_back(54);
265     v5[2].push_back(51);v5[3].push_back(52);v5[13].push_back(53);v5[14].push_back(54);
266     v5[3].push_back(51);v5[4].push_back(52);v5[14].push_back(53);v5[15].push_back(54);
267     v5[4].push_back(51);v5[5].push_back(52);v5[15].push_back(53);v5[16].push_back(54);
268     v5[6].push_back(51);v5[7].push_back(52);v5[17].push_back(53);v5[18].push_back(54);
269     v5[10].push_back(51);v5[11].push_back(52);v5[21].push_back(53);v5[22].push_back(54);
270     v5[17].push_back(51);v5[18].push_back(52);v5[28].push_back(53);v5[29].push_back(54);
271     v5[21].push_back(51);v5[22].push_back(52);v5[32].push_back(53);v5[33].push_back(54);
272     v5[28].push_back(51);v5[29].push_back(52);v5[39].push_back(53);v5[40].push_back(54);
273     v5[32].push_back(51);v5[33].push_back(52);v5[43].push_back(53);v5[44].push_back(54);
274     v5[39].push_back(51);v5[40].push_back(52);v5[50].push_back(53);v5[51].push_back(54);
275     v5[43].push_back(51);v5[44].push_back(52);v5[54].push_back(53);v5[55].push_back(54);
276     v5[45].push_back(51);v5[46].push_back(52);v5[56].push_back(53);v5[57].push_back(54);
277     v5[46].push_back(51);v5[47].push_back(52);v5[57].push_back(53);v5[58].push_back(54);
278     v5[47].push_back(51);v5[48].push_back(52);v5[58].push_back(53);v5[59].push_back(54);
279     v5[48].push_back(51);v5[49].push_back(52);v5[59].push_back(53);v5[60].push_back(54);
280     v5[1].push_back(55);v5[2].push_back(55);v5[3].push_back(55);v5[4].push_back(55);v5[5].push_back(55);v5[6].push_back(55);
281     v5[11].push_back(55);v5[17].push_back(55);v5[22].push_back(55);v5[28].push_back(55);v5[33].push_back(55);v5[39].push_back(55);
282     v5[44].push_back(55);v5[50].push_back(55);v5[55].push_back(55);v5[56].push_back(55);v5[57].push_back(55);v5[58].push_back(55);
283     v5[59].push_back(55);v5[60].push_back(55);
284 }
285 int main()
286 {
287     init();
288     int _;cin>>_;
289     while(_--){
290         int n;cin>>n;
291         if(n==0){
292             int k;cin>>k;while(k--){int a;cin>>a;}
293             cout<<0<<endl;
294         }
295         else if(n==1){
296             bool flag = false;
297             int k;cin>>k;
298             while(k--){
299                 int a;cin>>a;
300                 flag = true;
301             }
302             if(flag){
303                 cout<<0<<endl;
304             }else{
305                 cout<<1<<endl;
306             }
307         }
308         else if(n==2){
309             dlx.init(12,5);
310             int vis[6] = {0};
311             int vis2[13] = {0};
312             int k;cin>>k;
313             for(int i=0;i<k;i++){
314                 int a;cin>>a;vis2[a] = 1;
315                 for(int j=0;j<v2[a].size();j++){
316                     int v = v2[a][j];
317                     if(vis[v]==0) vis[v]=1,dlx.removeC(v);
318                 }
319             }
320             for(int i=1;i<=12;i++){
321                 if(vis2[i]) continue;
322                 for(int j=0;j<v2[i].size();j++){
323                     int v = v2[i][j];
324                     if(vis[v]) continue;
325                     dlx.Link(i,v);
326                 }
327             }
328             dlx.ansd=INF;
329             dlx.Dance(0);
330             cout<<dlx.ansd<<endl;
331         }
332         else if(n==3){
333             dlx.init(24,14);
334             int vis[15] = {0};
335             int vis2[25] = {0};
336             int k;cin>>k;
337             for(int i=0;i<k;i++){
338                 int a;cin>>a;vis2[a] = 1;
339                 for(int j=0;j<v3[a].size();j++){
340                     int v = v3[a][j];
341                     if(vis[v]==0) vis[v]=1,dlx.removeC(v);
342                 }
343             }
344             for(int i=1;i<=24;i++){
345                 if(vis2[i]) continue;
346                 for(int j=0;j<v3[i].size();j++){
347                     int v = v3[i][j];
348                     if(vis[v]) continue;
349                     dlx.Link(i,v);
350                 }
351             }
352             dlx.ansd=INF;
353             dlx.Dance(0);
354             cout<<dlx.ansd<<endl;
355         }
356         else if(n==4){
357             dlx.init(40,30);
358             int vis[31] = {0};
359             int vis2[41] = {0};
360             int k;cin>>k;
361             for(int i=0;i<k;i++){
362                 int a;cin>>a;vis2[a] = 1;
363                 for(int j=0;j<v4[a].size();j++){
364                     int v = v4[a][j];
365                     if(vis[v]==0) vis[v]=1,dlx.removeC(v);
366                 }
367             }
368             for(int i=1;i<=40;i++){
369                 if(vis2[i]) continue;
370                 for(int j=0;j<v4[i].size();j++){
371                     int v = v4[i][j];
372                     if(vis[v]) continue;
373                     dlx.Link(i,v);
374                 }
375             }
376             dlx.ansd=INF;
377             dlx.Dance(0);
378             cout<<dlx.ansd<<endl;
379         }
380         else if(n==5){
381             dlx.init(60,55);
382             int vis[56] = {0};
383             int vis2[61] = {0};
384             int k;cin>>k;
385             for(int i=0;i<k;i++){
386                 int a;cin>>a;vis2[a] = 1;
387                 for(int j=0;j<v5[a].size();j++){
388                     int v = v5[a][j];
389                     if(vis[v]==0) vis[v]=1,dlx.removeC(v);
390                 }
391             }
392             for(int i=1;i<=60;i++){
393                 if(vis2[i]) continue;
394                 for(int j=0;j<v5[i].size();j++){
395                     int v = v5[i][j];
396                     if(vis[v]) continue;
397                     dlx.Link(i,v);
398                 }
399             }
400             dlx.ansd=INF;
401             dlx.Dance(0);
402             cout<<dlx.ansd<<endl;
403         }
404     }
405     return 0;
406 }
View Code

对了,有一个更快捷的Link,因为有规律,我就不重新码一遍了,详细看大牛博客https://blog.csdn.net/Scar_Halo/article/details/84108288



 Squiggly Sudoku HDU - 4069

题意:一个特殊的9宫格,行和列不能重复,特殊方格内不能重复;128,左边缘;64,下边缘;32,右边缘;16,上边缘;

算法:预处理+DLinks

思路:预处理就是将输入的数字解码,还原成数字,并且标记是属于哪一个特殊九宫格内;行和上面九宫格差不多,列最后一个需要改动一下,就是正常九宫格改成编号为特殊九宫格;

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int INF = 0x3f3f3f3f;
 13 const int N = 9;
 14 const int MaxN = N*N*N + 10;
 15 const int MaxM = N*N*4 + 10;
 16 const int maxnode = MaxN*4 + MaxM + 10;
 17 
 18 int g[82],box[82];
 19 bool vis[82];
 20 
 21 struct DLX{
 22     int n,m,size;
 23     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 24     int H[MaxN],S[MaxM];
 25     int ansd,ans[MaxN];
 26     void init(int _n,int _m){
 27         n = _n , m = _m;
 28         for(int i = 0;i <= m;i++){
 29             S[i] = 0;
 30             U[i] = D[i] = i;
 31             L[i]  = i-1;
 32             R[i] = i+1;
 33         }
 34         R[m] = 0, L[0] = m, size = m;
 35         for(int i = 1;i <= n; i++) H[i] = -1;
 36     }
 37     void Link(int r,int c){
 38         ++S[Col[++size]=c];
 39         Row[size] = r;
 40         D[size] = D[c];
 41         U[D[c]] = size;
 42         U[size] = c;
 43         D[c] = size;
 44         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 45         else{
 46             R[size] = R[H[r]];
 47             L[R[H[r]]] = size;
 48             L[size] = H[r];
 49             R[H[r]] = size;
 50         }
 51     }
 52     void remove(int c){
 53         L[R[c]] = L[c] , R[L[c]] = R[c];
 54         for(int i = D[c];i != c;i = D[i])
 55             for(int j = R[i];j != i;j = R[j]){
 56                 U[D[j]] = U[j] , D[U[j]] = D[j] , --S[Col[j]];
 57         }
 58     }
 59     void resume(int c){
 60         for(int i = U[c];i != c;i = U[i])
 61             for(int j = L[i];j != i;j = L[j]){
 62                 ++S[Col[U[D[j]]=D[U[j]]=j]];
 63         }
 64         L[R[c]] = R[L[c]] = c;
 65     }
 66     bool Dance(int d){
 67         if(R[0] == 0){
 68             ansd++;
 69             if(ansd>=2) return true;
 70             for(int i = 0;i < d;i++) g[(ans[i]-1)/9] = (ans[i]-1)%9 + 1;
 71             return false;
 72         }
 73         int c = R[0];
 74         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 75         remove(c);
 76         for(int i = D[c];i != c;i = D[i]){
 77             ans[d] = Row[i];
 78             for(int j = R[i];j != i;j = R[j]) remove(Col[j]);
 79             if(Dance(d+1)) return true;
 80             for(int j = L[i];j != i;j = L[j]) resume(Col[j]);
 81         }
 82         resume(c);
 83         return false;
 84     }
 85 };
 86 void place(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k){
 87     r = (i*N+j)*N + k;
 88     c1 = i*N+j+1;
 89     c2 = N*N + i*N + k;
 90     c3 = N*N*2 + j*N + k;
 91     c4 = N*N*3 + (box[i*N+j]-1)*N + k;
 92 }
 93 DLX dlx;
 94 
 95 void getNum(int id,int num){
 96     if(vis[id]) return;
 97     vis[id] = true;box[id] = num;
 98     if(g[id]>=128) g[id]-=128;
 99     else getNum(id-1,num);
100     if(g[id]>=64) g[id]-=64;
101     else getNum(id+9,num);
102     if(g[id]>=32) g[id]-=32;
103     else getNum(id+1,num);
104     if(g[id]>=16) g[id]-=16;
105     else getNum(id-9,num);
106 }
107 void init(){
108     memset(vis,false,sizeof vis);
109     int num=1;
110     for(int i=0;i<81;i++) if(!vis[i]){
111         getNum(i,num++);
112     }
113 }
114 
115 int main()
116 {
117     int _,cas=1;cin>>_;
118     while(_--){
119         cout<<"Case "<<cas++<<":"<<endl;
120         for(int i=0;i<81;i++) cin>>g[i];
121         init();
122         dlx.init(N*N*N,N*N*4);
123         int r,c1,c2,c3,c4;
124         for(int i = 0;i < N;i++)
125               for(int j = 0;j < N;j++)
126                   for(int k = 1;k <= N;k++)
127                       if(g[i*N+j] == 0 || g[i*N+j] == k){
128                          place(r,c1,c2,c3,c4,i,j,k);
129                          dlx.Link(r,c1) , dlx.Link(r,c2) ,  dlx.Link(r,c3) , dlx.Link(r,c4);
130                      }
131         dlx.ansd = 0;
132         dlx.Dance(0);
133         if(dlx.ansd==0) puts("No solution");
134         else if(dlx.ansd>=2) puts("Multiple Solutions");
135         else{
136             int num=0;
137             for(int i=0;i<9;i++){
138                 for(int j=0;j<9;j++) cout<<g[num++];cout<<endl;
139             }
140         }
141     }
142     return 0;
143 }
View Code


 DivisibilityHDU - 3335 

题意:给你一堆数,问你找出一个最大子集合里面的数互相除不尽?

算法:可覆盖

思路:行和列都是是数字Id序列;这里如果一个数a能除尽另一个数b,那么dlx.Link(a,b),dlx.Link(b,a);然后就是最终答案中,两个数互相除不尽,但是存在两个数可以除尽同一个不在答案的数,所以是可覆盖Dlinks;

 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <cstdio>
 7 #include <map>
 8 #include <math.h>
 9 
10 using namespace std;
11 
12 #define LL long long
13 
14 const int MaxN = 1000 + 10;
15 const int MaxM = 1000 + 10;
16 const int maxnode = MaxN*MaxM;
17 const int INF = 0x3f3f3f3f;
18 
19 struct DLX{
20     int n,m,size;
21     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
22     int H[MaxN],S[MaxM];
23     int ansd;
24     void init(int _n,int _m){
25         n = _n , m = _m;
26         for(int i = 0;i <= m;i++){
27             S[i] = 0;
28             U[i] = D[i] = i;
29             L[i]  = i-1;
30             R[i] = i+1;
31         }
32         R[m] = 0, L[0] = m, size = m;
33         for(int i = 1;i <= n; i++) H[i] = -1;
34     }
35     void Link(int r,int c){
36         ++S[Col[++size]=c];
37         Row[size] = r;
38         D[size] = D[c];
39         U[D[c]] = size;
40         U[size] = c;
41         D[c] = size;
42         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
43         else{
44             R[size] = R[H[r]];
45             L[R[H[r]]] = size;
46             L[size] = H[r];
47             R[H[r]] = size;
48         }
49     }
50     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
51     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
52     bool v[MaxM];
53     int f(){
54         int ret = 0;
55         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
56         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
57             ret++;
58             v[c]=false;
59             for(int i = D[c];i != c;i = D[i])
60                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
61         }
62         return ret;
63     }
64     void Dance(int d){
65         if(d + f() <= ansd) return ;
66         if(R[0] == 0){
67             if(d > ansd) ansd = d;
68             return ;
69         }
70         int c = R[0];
71         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
72         for(int i = D[c];i != c;i = D[i]){
73             remove(i);
74             for(int j = R[i];j != i;j = R[j]) remove(j);
75             Dance(d+1);
76             for(int j = L[i];j != i;j = L[j]) resume(j);
77             resume(i);
78         }
79     }
80 };
81 DLX dlx;
82 int main()
83 {
84     int _;cin>>_;
85     while(_--){
86         LL num[MaxN];
87         int a;cin>>a;for(int i=1;i<=a;i++) cin>>num[i];
88         dlx.init(a,a);
89         for(int i=1;i<=a;i++)
90             for(int j=i;j<=a;j++)
91                 if( num[i]%num[j]==0 || num[j]%num[i]==0 ){
92                     dlx.Link(i,j);if(i!=j) dlx.Link(j,i);
93                 } 
94         dlx.ansd=0;
95         dlx.Dance(0);
96         cout<<dlx.ansd<<endl;
97     }
98     return 0;
99 }
View Code


 A simple math problem. HDU - 4979

说实话这题没看太懂什么意思?后面看了别人博客才懂...(我太懒了!摘自https://blog.csdn.net/qq_40679299/article/details/86417994)

 

题意:Cnm(n在下面);行是Cnm,列是Cnr;因为n>=m>=r;所以Cnm每一行的抉择必然包含着一个或多个Cnr;问至少要选择多少行,才满足所有列;

算法:可覆盖(因为最优解里面的列是重叠的)+ 打表(不然TLE)

思路:三步走:确定行列;建立联系;然后Dance函数;

1.dlx.init(Cnm,Cnr) 2.因为看了别人代码所以这里自己没有过多思考,就是直接用位运算来Link,暴力从(1~1<<n)找二进制1个数为m的数tmp,然后在进行for(int j=tmp;j>0;j=tmp&(j-1)) 这里循环列举 tmp 所有子集合,找出子集合中二进制1个数为r的数;然后进行Link操作。3.然后进行可覆盖Dance(0);

易错点:这里打表,把所有n,m,k情况都记录到一个数组里,然后输出即可;

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int MaxN = 70 + 10;
 13 const int MaxM = 70 + 10;
 14 const int maxnode = MaxN*MaxM;
 15 const int INF = 0x3f3f3f3f;
 16 struct DLX{
 17     int n,m,size;
 18     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 19     int H[MaxN],S[MaxM];
 20     int ansd;
 21     void init(int _n,int _m){
 22         n = _n , m = _m;
 23         for(int i = 0;i <= m;i++){
 24             S[i] = 0;
 25             U[i] = D[i] = i;
 26             L[i]  = i-1;
 27             R[i] = i+1;
 28         }
 29         R[m] = 0, L[0] = m, size = m;
 30         for(int i = 1;i <= n; i++) H[i] = -1;
 31     }
 32     void Link(int r,int c){
 33         ++S[Col[++size]=c];
 34         Row[size] = r;
 35         D[size] = D[c];
 36         U[D[c]] = size;
 37         U[size] = c;
 38         D[c] = size;
 39         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 40         else{
 41             R[size] = R[H[r]];
 42             L[R[H[r]]] = size;
 43             L[size] = H[r];
 44             R[H[r]] = size;
 45         }
 46     }
 47     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
 48     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
 49     bool v[MaxM];
 50     int f(){
 51         int ret = 0;
 52         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
 53         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
 54             ret++;
 55             v[c]=false;
 56             for(int i = D[c];i != c;i = D[i])
 57                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
 58         }
 59         return ret;
 60     }
 61     void Dance(int d){
 62         if(d + f() >= ansd) return ;
 63         if(R[0] == 0){
 64             if(d < ansd) ansd = d;
 65             return ;
 66         }
 67         int c = R[0];
 68         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 69         for(int i = D[c];i != c;i = D[i]){
 70             remove(i);
 71             for(int j = R[i];j != i;j = R[j]) remove(j);
 72             Dance(d+1);
 73             for(int j = L[i];j != i;j = L[j]) resume(j);
 74             resume(i);
 75         }
 76     }
 77 };
 78 DLX dlx;
 79 int c[9][9],cnt[1<<8];
 80 void getOne(){cnt[0] = 0;for(int i=1;i<(1<<8);i++) cnt[i] = cnt[i>>1] + (i&1);}
 81 void getCNM(){
 82     for(int i=1;i<=8;i++){
 83         c[i][0] = c[i][i] = 1;
 84         for(int j=1;j<i;j++)
 85             c[i][j] = c[i-1][j] + c[i-1][j-1];
 86     }
 87     //for(int i=1;i<=8;i++){for(int j=0;j<=i;j++) cout<<c[i][j]<<" ";cout<<endl;}
 88 }
 89 void solve(int n,int m,int r){
 90     dlx.init(c[n][m],c[n][r]);
 91     int col[1<<n],num = 1;
 92     for(int i=1;i<(1<<n);i++) if(cnt[i]==r) col[i] = num++;
 93     num = 1;
 94     for(int i=1;i<(1<<n);i++) if(cnt[i]==m){
 95         for(int j=i;j>0;j=i&(j-1)) if(cnt[j]==r){
 96             dlx.Link(num,col[j]);
 97         }num++;
 98     }
 99     dlx.ansd=INF;
100     dlx.Dance(0);
101     cout<<dlx.ansd;
102 }
103 int main()
104 {
105     getOne();getCNM();
106     puts("{");
107     for(int n=1;n<=8;n++){
108         puts("{");
109         for(int m=1;m<=n;m++){
110             cout<<"{";
111             for(int r=1;r<=m;r++){
112                 if(r>1) cout<<",";
113                 solve(n,m,r);
114             }
115             if(m==n)puts("}");
116             else cout<<"},";
117         }
118         if(n==8)puts("}");
119         else puts("},");
120     }puts("}");
121     return 0;
122 }
打表代码
 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <cstdio>
 7 #include <map>
 8 #include <math.h>
 9 
10 using namespace std;
11 
12 int ans[8][8][8]={
13     {{1}},
14     {{2},{1,1}},
15     {{3},{2,3},{1,1,1}},
16     {{4},{2,6},{2,3,4},{1,1,1,1}},
17     {{5},{3,10},{2,4,10},{2,3,4,5},{1,1,1,1,1}},
18     {{6},{3,15},{2,6,20},{2,3,6,15},{2,3,4,5,6},{1,1,1,1,1,1}},
19     {{7},{4,21},{3,7,35},{2,5,12,35},{2,3,5,9,21},{2,3,4,5,6,7},{1,1,1,1,1,1,1}},
20     {{8},{4,28},{3,11,56},{2,6,14,70},{2,4,8,20,56},{2,3,4,7,12,28},{2,3,4,5,6,7,8},{1,1,1,1,1,1,1,1}}
21 };
22 
23 int main()
24 {
25     int _,cas=1;cin>>_;
26     while(_--){
27         cout<<"Case #"<<cas++<<": ";
28         int n,m,k;cin>>n>>m>>k;
29         cout<<ans[n-1][m-1][k-1]<<endl;
30     }
31     return 0;
32 }
View Code


 AirportHDU - 5046

 题意:给你一个地图,有N城市,他们之间距离是坐标曼哈顿距离,给你一个数K,问如何在N个城市中挑选K个城市建机场,才能使城市到机场的最远距离最小?

算法:二分+可覆盖DLinks

思路:首先,这里是N个城市,互相之间有距离,当一个城市变成机场之后,机场之间的距离会变成0,整个城市就只存在非机场城市到机场的距离,答案就是这些距离中最大的那个边;

   反向思维,通过二分枚举距离为答案,然后把大于这个距离的边都消除掉,留下的边,是否能连通整个城市网络?注意这里机场与机场之间不需要连通

   列是所有城市,行也是所有城市,通过消除后的边来进行Link,注意这里自身也要Link;当城市选举位机场,那么他所能连通的城市列都可以跟着消减掉;只要选举城市数量小于等于K,表示这个二分距离是可行,继续二分;

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int MaxN = 60 + 10;
 13 const int MaxM = 60 + 10;
 14 const int maxnode = MaxN*MaxM;
 15 const int INF = 0x3f3f3f3f;
 16 
 17 #define LL long long
 18 
 19 struct DLX{
 20     int n,m,size;
 21     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 22     int H[MaxN],S[MaxM];
 23     int ansd;
 24     void init(int _n,int _m){
 25         n = _n , m = _m;
 26         for(int i = 0;i <= m;i++){
 27             S[i] = 0;
 28             U[i] = D[i] = i;
 29             L[i]  = i-1;
 30             R[i] = i+1;
 31         }
 32         R[m] = 0, L[0] = m, size = m;
 33         for(int i = 1;i <= n; i++) H[i] = -1;
 34     }
 35     void Link(int r,int c){
 36         ++S[Col[++size]=c];
 37         Row[size] = r;
 38         D[size] = D[c];
 39         U[D[c]] = size;
 40         U[size] = c;
 41         D[c] = size;
 42         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 43         else{
 44             R[size] = R[H[r]];
 45             L[R[H[r]]] = size;
 46             L[size] = H[r];
 47             R[H[r]] = size;
 48         }
 49     }
 50     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
 51     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
 52     bool v[MaxM];
 53     int f(){
 54         int ret = 0;
 55         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
 56         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
 57             ret++;
 58             v[c]=false;
 59             for(int i = D[c];i != c;i = D[i])
 60                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
 61         }
 62         return ret;
 63     }
 64     void Dance(int d){
 65         if(d + f() >= ansd) return ;
 66         if(R[0] == 0){
 67             if(d < ansd) ansd = d;
 68             return ;
 69         }
 70         int c = R[0];
 71         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 72         for(int i = D[c];i != c;i = D[i]){
 73             remove(i);
 74             for(int j = R[i];j != i;j = R[j]) remove(j);
 75             Dance(d+1);
 76             for(int j = L[i];j != i;j = L[j]) resume(j);
 77             resume(i);
 78         }
 79     }
 80 };
 81 DLX dlx;
 82 int n,k;
 83 LL cityX[62],cityY[62];
 84 struct node{
 85     LL dis;
 86     int id;
 87     node(LL a,int b):dis(a),id(b) {}
 88     bool operator <(const node &a){
 89         return dis < a.dis;
 90     }
 91 };
 92 vector<node> city[62];
 93 
 94 bool check(LL x){
 95     dlx.init(n,n);
 96     for(int i=1;i<=n;i++){
 97         dlx.Link(i,i);
 98         for(int j=0;j<city[i].size();j++){
 99             if(city[i][j].dis>x) break;
100             dlx.Link(i,city[i][j].id);
101         }
102     }
103     dlx.ansd=INF;
104     dlx.Dance(0);
105     return dlx.ansd>k?false:true;
106 }
107 
108 void solve(){
109     LL left = 0 , right = 4e9;
110     while(left<=right){
111         LL mid = left + right >> 1;
112         if(check(mid)) right = mid - 1;
113         else left = mid +1 ;
114     }
115     cout<<left<<endl;
116 }
117 
118 int main()
119 {
120     int _,cas=1;cin>>_;
121     while(_--){
122         cout<<"Case #"<<cas++<<": ";
123         cin>>n>>k;
124         for(int i=1;i<=n;i++) cin>>cityX[i]>>cityY[i],city[i].clear();
125         for(int i=1;i<=n;i++){
126             for(int j=i+1;j<=n;j++){
127                 LL d = abs(cityX[i] - cityX[j]) + abs(cityY[i] - cityY[j]);
128                 city[i].push_back(node(d,j));city[j].push_back(node(d,i));
129             }
130         }
131         for(int i=1;i<=n;i++) sort(city[i].begin(),city[i].end());
132         solve();
133     }
134     return 0;
135 }
View Code
  1 #include <iostream>
  2 #include <vector>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <cstdio>
  7 #include <map>
  8 #include <math.h>
  9 
 10 using namespace std;
 11 
 12 const int MaxN = 60 + 10;
 13 const int MaxM = 60 + 10;
 14 const int maxnode = MaxN*MaxM;
 15 const int INF = 0x3f3f3f3f;
 16 
 17 #define LL long long
 18 
 19 int n,k;
 20 
 21 struct DLX{
 22     int n,m,size;
 23     int U[maxnode],D[maxnode],R[maxnode],L[maxnode],Row[maxnode],Col[maxnode];
 24     int H[MaxN],S[MaxM];
 25     int ansd;
 26     void init(int _n,int _m){
 27         n = _n , m = _m;
 28         for(int i = 0;i <= m;i++){
 29             S[i] = 0;
 30             U[i] = D[i] = i;
 31             L[i]  = i-1;
 32             R[i] = i+1;
 33         }
 34         R[m] = 0, L[0] = m, size = m;
 35         for(int i = 1;i <= n; i++) H[i] = -1;
 36     }
 37     void Link(int r,int c){
 38         ++S[Col[++size]=c];
 39         Row[size] = r;
 40         D[size] = D[c];
 41         U[D[c]] = size;
 42         U[size] = c;
 43         D[c] = size;
 44         if(H[r] < 0 ) H[r] = L[size] = R[size] = size;
 45         else{
 46             R[size] = R[H[r]];
 47             L[R[H[r]]] = size;
 48             L[size] = H[r];
 49             R[H[r]] = size;
 50         }
 51     }
 52     void remove(int c) {for(int i = D[c];i != c;i = D[i]) L[R[i]] = L[i] , R[L[i]] = R[i];}
 53     void resume(int c){for(int i = U[c];i != c;i = U[i]) L[R[i]] = R[L[i]] = i;}
 54     bool v[MaxM];
 55     int f(){
 56         int ret = 0;
 57         for(int c = R[0];c != 0; c = R[c]) v[c] = true;
 58         for(int c = R[0];c != 0;c = R[c]) if(v[c]){
 59             ret++;
 60             v[c]=false;
 61             for(int i = D[c];i != c;i = D[i])
 62                 for(int j = R[i];j != i;j = R[j]) v[Col[j]] = false;
 63         }
 64         return ret;
 65     }
 66     bool Dance(int d){
 67         if(d + f() > k) return false;
 68         if(R[0] == 0) return d<=k;
 69         int c = R[0];
 70         for(int i = R[0];i != 0;i = R[i]) if(S[i] < S[c]) c = i;
 71         for(int i = D[c];i != c;i = D[i]){
 72             remove(i);
 73             for(int j = R[i];j != i;j = R[j]) remove(j);
 74             if(Dance(d+1)) return true;
 75             for(int j = L[i];j != i;j = L[j]) resume(j);
 76             resume(i);
 77         }
 78         return false;
 79     }
 80 };
 81 DLX dlx;
 82 LL cityX[62],cityY[62];
 83 struct node{
 84     LL dis;
 85     int id;
 86     node(LL a,int b):dis(a),id(b) {}
 87     bool operator <(const node &a){
 88         return dis < a.dis;
 89     }
 90 };
 91 vector<node> city[62];
 92 
 93 bool check(LL x){
 94     dlx.init(n,n);
 95     for(int i=1;i<=n;i++){
 96         dlx.Link(i,i);
 97         for(int j=0;j<city[i].size();j++){
 98             if(city[i][j].dis>x) break;
 99             dlx.Link(i,city[i][j].id);
100         }
101     }
102     return dlx.Dance(0);
103 }
104 
105 LL M[3650];
106 
107 void solve(int x){
108     int left = 0 , right = x;
109     while(left<=right){
110         int mid = left + right >> 1;
111         if(check(M[mid])) right = mid - 1;
112         else left = mid +1 ;
113     }
114     cout<<M[left]<<endl;
115 }
116 
117 int main()
118 {
119     int _,cas=1;cin>>_;
120     while(_--){
121         cout<<"Case #"<<cas++<<": ";
122         cin>>n>>k;
123         for(int i=1;i<=n;i++) cin>>cityX[i]>>cityY[i],city[i].clear();
124         int num = 1;M[0]=0;
125         for(int i=1;i<=n;i++){
126             for(int j=i+1;j<=n;j++){
127                 LL d = abs(cityX[i] - cityX[j]) + abs(cityY[i] - cityY[j]);
128                 M[num++] = d;
129                 city[i].push_back(node(d,j));city[j].push_back(node(d,i));
130             }
131         }
132         for(int i=1;i<=n;i++) sort(city[i].begin(),city[i].end());
133         sort(M,M+num);
134         num = unique(M,M+num)-M;
135         solve(num-1);
136     }
137     return 0;
138 }
优化代码


 

 

 
posted @ 2022-09-07 05:49  Bug_Clearlove  阅读(28)  评论(0编辑  收藏  举报