【总结】Dancing Links

1、精确覆盖。

View Code
 1 #include<cstdio>

 2 #define INF 0x7FFFFFFF

 3 #define MAXN 1000010

 4 int n, m, size;

 5 int L[MAXN], R[MAXN], U[MAXN], D[MAXN], H[MAXN];

 6 int S[MAXN], C[MAXN], X[MAXN], Q[MAXN];

 7 void Init()

 8 {

 9     int i;

10     for (i = 0; i <= m; i++)

11     {

12         S[i] = 0;

13         L[i + 1] = i;

14         R[i] = i + 1;

15         U[i] = D[i] = i;

16     }

17     R[m] = 0;

18     size = m + 1;

19 }

20 void Remove(int c)

21 {

22     int i, j;

23     R[L[c]] = R[c];

24     L[R[c]] = L[c];

25     for (i = D[c]; i != c; i = D[i])

26     {

27         for (j = R[i]; j != i; j = R[j])

28         {

29             D[U[j]] = D[j];

30             U[D[j]] = U[j];

31             S[C[j]]--;

32         }

33     }

34 }

35 void Resume(int c)

36 {

37     int i, j;

38     R[L[c]] = c;

39     L[R[c]] = c;

40     for (i = D[c]; i != c; i = D[i])

41     {

42         for (j = R[i]; j != i; j = R[j])

43         {

44             U[D[j]] = j;

45             D[U[j]] = j;

46             S[C[j]]++;

47         }

48     }

49 }

50 void Link(int r, int c)

51 {

52     D[size] = D[c];

53     U[size] = c;

54     U[D[c]] = size;

55     D[c] = size;

56     if (H[r] < 0)

57         H[r] = L[size] = R[size] = size;

58     else

59     {

60         L[size] = H[r];

61         R[size] = R[H[r]];

62         L[R[H[r]]] = size;

63         R[H[r]] = size;

64     }

65     S[c]++;

66     C[size] = c;

67     X[size++] = r;

68 }

69 bool Dance(int now)

70 {

71     int i, j, c, temp;

72     if (R[0] == 0)

73         return true;

74     for (temp = INF, i = R[0]; i; i = R[i])

75     {

76         if (S[i] < temp)

77         {

78             c = i;

79             temp = S[i];

80         }

81     }

82     Remove(c);

83     for (i = D[c]; i != c; i = D[i])

84     {

85         for (j = R[i]; j != i; j = R[j])

86             Remove(C[j]);

87         if (Dance(now + 1))

88             return true;

89         for (j = L[i]; j != i; j = L[j])

90             Resume(C[j]);

91     }

92     Resume(c);

93     return false;

94 }

 

2、重复覆盖。

View Code
  1 #include<cstdio>

  2 #include<cstring>

  3 #include<algorithm>

  4 #define MAXN 110

  5 #define MAXM 1000000

  6 #define INF 0x7FFFFFFF

  7 using namespace std;

  8 int G[MAXN][MAXN];

  9 int L[MAXM], R[MAXM], U[MAXM], D[MAXM];

 10 int size, ans, S[MAXM], H[MAXM], C[MAXM];

 11 bool vis[MAXN * 100];

 12 void Link(int r, int c)

 13 {

 14     U[size] = c;

 15     D[size] = D[c];

 16     U[D[c]] = size;

 17     D[c] = size;

 18     if (H[r] < 0)

 19         H[r] = L[size] = R[size] = size;

 20     else

 21     {

 22         L[size] = H[r];

 23         R[size] = R[H[r]];

 24         L[R[H[r]]] = size;

 25         R[H[r]] = size;

 26     }

 27     S[c]++;

 28     C[size++] = c;

 29 }

 30 void Remove(int c)

 31 {

 32     int i;

 33     for (i = D[c]; i != c; i = D[i])

 34     {

 35         L[R[i]] = L[i];

 36         R[L[i]] = R[i];

 37     }

 38 }

 39 void Resume(int c)

 40 {

 41     int i;

 42     for (i = D[c]; i != c; i = D[i])

 43         L[R[i]] = R[L[i]] = i;

 44 }

 45 int A()

 46 {

 47     int i, j, k, res;

 48     memset(vis, false, sizeof(vis));

 49     for (res = 0, i = R[0]; i; i = R[i])

 50     {

 51         if (!vis[i])

 52         {

 53             res++;

 54             for (j = D[i]; j != i; j = D[j])

 55             {

 56                 for (k = R[j]; k != j; k = R[k])

 57                     vis[C[k]] = true;

 58             }

 59         }

 60     }

 61     return res;

 62 }

 63 void Dance(int now)

 64 {

 65     if (R[0] == 0)

 66         ans = min(ans, now);

 67     else if (now + A() < ans)

 68     {

 69         int i, j, temp, c;

 70         for (temp = INF,i = R[0]; i; i = R[i])

 71         {

 72             if (temp > S[i])

 73             {

 74                 temp = S[i];

 75                 c = i;

 76             }

 77         }

 78         for (i = D[c]; i != c; i = D[i])

 79         {

 80             Remove(i);

 81             for (j = R[i]; j != i; j = R[j])

 82                 Remove(j);

 83             Dance(now + 1);

 84             for (j = L[i]; j != i; j = L[j])

 85                 Resume(j);

 86             Resume(i);

 87         }

 88     }

 89 }

 90 void Init(int m)

 91 {

 92     int i;

 93     for (i = 0; i <= m; i++)

 94     {

 95         R[i] = i + 1;

 96         L[i + 1] = i;

 97         U[i] = D[i] = i;

 98         S[i] = 0;

 99     }

100     R[m] = 0;

101     size = m + 1;

102 }

 

3精确覆盖与重复覆盖的区别:

精确覆盖:给定一个01矩阵,现在要选择一些行,使得每一列有且仅有一个1。

每次选定一个元素个数最少的列,从该列中选择一行加入答案,删除该行所有的列以及与该行冲突的行。

重复覆盖:给定一个01矩阵,现在要选择一些行,使得每一列至少有一个1。

每次选定一个元素个数最少的列,从该列中选择一行加入答案,删除该行所有的列。与该行冲突的行可能满足重复覆盖。

 

4、精确覆盖:

 

HUST1017 Exact cover

POJ3740 Easy Finding

ZOJ3209 Treasure Map

POJ3074 Sudoku

POJ3076 Sudoku

POJ2676 Sudoku

HDU2780 Su-Su-Sudoku

HDU3111 Sudoku

HDU3909 Sudoku

HDU4069 Squiggly Sudoku

HDU3663 Power Stations

FOJ2076 SUDOKU

SPOJ1771 Yet Another N-Queen Problem

UVa387 A Puzzling Problem

HDU4210 Su-domino-ku

 

 

5、重复覆盖:

 

HDU3498 whosyourdaddy

HDU2119 Matrix

HDU2828 Lamp

HDU3529 Bomberman - Just Search!

 HDU3335 Divisibility

 HDU2295 Radar

 HDU3656 Fire station

HDU3156 Repair Depots

POJ1084 Square Destroyer

HDU3957 Street Fighter




你可能感兴趣的:(link)