首页 > 代码库 > dancing link模板
dancing link模板
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<iomanip> 7 using namespace std; 8 9 const int n=729,m=324; 10 bool mx[2000][2000];//数独转化过来的01矩阵 11 int map[10][10],cnt[2000],head,cur,ans; 12 int sqr[10][10]={{0,0,0,0,0,0,0,0,0,0}, //九宫格的编号 13 {0,1,1,1,4,4,4,7,7,7}, 14 {0,1,1,1,4,4,4,7,7,7}, 15 {0,1,1,1,4,4,4,7,7,7}, 16 {0,2,2,2,5,5,5,8,8,8}, 17 {0,2,2,2,5,5,5,8,8,8}, 18 {0,2,2,2,5,5,5,8,8,8}, 19 {0,3,3,3,6,6,6,9,9,9}, 20 {0,3,3,3,6,6,6,9,9,9}, 21 {0,3,3,3,6,6,6,9,9,9}}; 22 23 int w[10][10]={{0,0,0,0,0,0,0,0,0,0}, 24 {0,6,6,6,6,6,6,6,6,6}, 25 {0,6,7,7,7,7,7,7,7,6}, 26 {0,6,7,8,8,8,8,8,7,6}, 27 {0,6,7,8,9,9,9,8,7,6}, 28 {0,6,7,8,9,10,9,8,7,6}, 29 {0,6,7,8,9,9,9,8,7,6}, 30 {0,6,7,8,8,8,8,8,7,6}, 31 {0,6,7,7,7,7,7,7,7,6}, 32 {0,6,6,6,6,6,6,6,6,6}}; 33 34 struct point 35 { 36 int row,lc,rc,up,down,col;//元素的上下左右,行号和列标 37 }node[2000*2000]; 38 39 inline int id(int x,int y) 40 { 41 return (x-1)*9+y;//格子(x,y)的编号 42 } 43 44 void init(int c)//初始化列标元素 45 { 46 for (int i=0;i<=c;i++) 47 { 48 node[i].lc=i-1; 49 node[i].rc=i+1; 50 node[i].up=node[i].down=node[i].col=i; 51 } 52 node[0].lc=c; 53 node[c].rc=0; 54 } 55 56 void build_link()//把01矩阵中的 1 用dancing link 连接 57 { 58 cur=m; 59 for (int i=1;i<=n;i++) 60 { 61 int start,pre; 62 start=pre=cur+1; 63 for (int j=1;j<=m;j++) 64 if (mx[i][j]) 65 { 66 cur++; 67 cnt[j]++; 68 node[cur].row=i; 69 70 node[cur].lc=pre; 71 node[cur].rc=start; 72 node[pre].rc=cur; 73 node[start].lc=cur; 74 75 node[cur].col=j; 76 node[cur].up=node[j].up; 77 node[cur].down=j; 78 node[node[j].up].down=cur; 79 node[j].up=cur; 80 pre=cur; 81 } 82 } 83 } 84 85 inline void cover(int c)//删除冲突元素 86 { 87 for (int i=node[c].up;i!=c;i=node[i].up) 88 for (int j=node[i].rc;j!=i;j=node[j].rc) 89 { 90 node[node[j].up].down=node[j].down; 91 node[node[j].down].up=node[j].up; 92 cnt[node[j].col]--; 93 } 94 node[node[c].lc].rc=node[c].rc; 95 node[node[c].rc].lc=node[c].lc; 96 } 97 98 inline void uncover(int c)//恢复冲突元素 99 {100 for (int i=node[c].up;i!=c;i=node[i].up)101 for (int j=node[i].rc;j!=i;j=node[j].rc)102 {103 node[node[j].up].down=j;104 node[node[j].down].up=j;105 cnt[node[j].col]++;106 }107 node[node[c].lc].rc=c;108 node[node[c].rc].lc=c;109 }110 111 void read_data()//把数独转化成01矩阵 112 {113 for (int i=1;i<=9;i++)114 for (int j=1;j<=9;j++)115 {116 scanf("%d",&map[i][j]);117 int c=id(i,j),t,k;118 if (map[i][j])//数独中本来有数,直接加入 119 {120 k=map[i][j];121 t=(c-1)*9+k;122 mx[t][c]=true;123 mx[t][81+9*(i-1)+k]=true;124 mx[t][162+9*(j-1)+k]=true;125 mx[t][243+(sqr[i][j]-1)*9+k]=true;126 }127 else 128 {129 for (k=1;k<=9;k++) //数独中本来没数,那么加入1-9的情况 130 {131 t=(c-1)*9+k;132 mx[t][c]=true;133 mx[t][81+9*(i-1)+k]=true;134 mx[t][162+9*(j-1)+k]=true;135 mx[t][243+(sqr[i][j]-1)*9+k]=true;136 }137 }138 }139 }140 141 bool dfs(int step,int score)142 {143 if (node[head].rc==head) //已经全部覆盖 144 {145 ans=max(score,ans);146 return true;147 }148 149 int i,j,c,t=210000,x,y,num,flag=0;150 for (i=node[head].rc;i!=head;i=node[i].rc) //启发式,每次处理元素最少的列 151 if (cnt[i]<t)152 {153 t=cnt[i];154 c=i;155 }156 if (t==0)157 return false;158 159 cover(c);//覆盖当前列 160 161 for (i=node[c].down;i!=c;i=node[i].down)162 {163 for (j=node[i].lc;j!=i;j=node[j].lc)//删除冲突的行 164 cover(node[j].col);165 num=(node[i].row-1)/9+1;166 x=(num-1)/9+1;167 y=num-9*(x-1);168 flag|=dfs(step+1,score+w[x][y]*(node[i].row-(num-1)*9));169 for (j=node[i].rc;j!=i;j=node[j].rc)//恢复删除冲突的行 170 uncover(node[j].col);171 }172 173 uncover(c);//恢复当前列 174 return flag;175 }176 177 void solve()178 {179 init(m);180 build_link();181 int flag=1;182 if (!dfs(1,0))183 printf("-1\n");184 else printf("%d\n",ans);185 }186 187 int main()188 {189 read_data();190 solve();191 return 0;192 }
dancing link模板
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。