舞动的dancing links poj 3740
来源:互联网 发布:软件开发合同范本 编辑:程序博客网 时间:2024/05/01 17:28
对于npc问题,我们似乎只能用搜索(或状压dp)。
但是,有时候,搜索的期望得分是满分,比如说,当dancing links跳舞的时候。
dancing link 作为双向链表,拥有优秀的性质,快速的删除和恢复,任何熟练掌握链表的人都可以轻易上手,更重要的是,它为搜索省去大量回朔时间,并且方便启发式进行(只需加估价数组(代码中s)),优美的操作就像绚丽的舞步。
由于是矩阵,所以采用十字链表(up,down,left,right) c记录列号,t记录行号,s记录该列还有多少节点(尽量选择节点少进行拓展)
poj 3740(未加启发式) 219ms
poj 3740(加启发式) 172ms
c++版
#include <cstdio>#include <algorithm>#include <cstring>#include <iostream>#include <string>#include <vector>#include <cassert>using namespace std;int g[100][500];int l[200000],r[200000],u[200000],d[200000],R[200000],C[200000];int row[200000],clo[200000],v[200000];int n,m,ss;int ori(){ ++ss; l[ss]=r[ss]=u[ss]=d[ss]=ss,R[ss]=C[ss]=0; return ss;}void linkud(int x,int y){d[x]=y,u[y]=x;}void linklr(int x,int y){r[x]=y,l[y]=x;}void add(int x,int y){ori(); R[ss]=row[x],C[ss]=clo[y];int last=u[clo[y]];linkud(last,ss),linkud(ss,clo[y]);last=l[row[x]];linklr(last,ss),linklr(ss,row[x]);}void build(){ ss=0; for (int i=1;i<=n;i++) row[i]=ori(); for (int i=0;i<=m;i++) clo[i]=ori(); for (int i=1;i<n;i++) linkud(row[i],row[i+1]); linkud(row[n],row[1]); for (int i=0;i<m;i++) linklr(clo[i],clo[i+1]); linklr(clo[m],clo[0]); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (g[i][j]) add(i,j);}void del(int x){linklr(l[x],r[x]);for (int i=x;d[i]!=x;) {i=d[i];for (int y=i;r[y]!=i;) {y=r[y];if (R[y] && C[y]) linkud(u[y],d[y]);}}}void rel(int x){linklr(l[x],x),linklr(x,r[x]);for (int i=x;u[i]!=x;) {i=u[i];for (int y=i;l[y]!=i;) {y=l[y];if (R[y] && C[y]) linkud(u[y],y),linkud(y,d[y]);}}}bool DLX(int s,int step){if (r[s]==s) return 1;int x;x=r[s],del(x);for (int i=x;d[i]!=x;) {i=d[i];//cout<<'!'<<i<<endl;for (int y=i;r[y]!=i;) {y=r[y];if (R[y] && C[y]) del(C[y]);}v[R[i]]=1;if (DLX(s,step+1)) return 1;v[R[i]]=0;for (int y=i;l[y]!=i;) {y=l[y];if (R[y] && C[y]) rel(C[y]);}}rel(x);return 0;}int main() { for (;scanf("%d%d",&n,&m)==2;) {//cout<<n<<' '<<m<<endl; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) scanf("%d",&g[i][j]); build(); if (DLX(clo[0],0)) { printf("Yes, I found it\n"); } else { printf("It is impossible\n"); } } return 0;}
- 舞动的dancing links poj 3740
- poj 3740 dancing links
- POJ 3740 Dancing Links
- poj 3740 dancing links
- poj 3740 Easy Finding(Dancing Links)
- POJ 3740 - Easy Finding (Dancing links)
- poj 3076 Sudoku //Dancing Links
- POJ 3076 Sudoku (dancing links)
- poj 3074 Sudoku(Dancing Links)
- poj 3740 Easy Finding//Dancing Links 或 状态压缩Dp
- ACM练级日志:POJ 3740 与Dancing Links
- poj 3740 Easy Finding(Dancing Links 精确覆盖)
- Dancing links ? Dancing links !
- POJ 3074 Sudoku (Dancing Links)
- POJ 2676 数独 Dancing-Links(DLX)
- poj 3704 Sudoku(Dancing Links)
- poj 3076 Sudoku(Dancing Links)
- 【Dancing Links舞蹈链】poj 3076 Sudoku
- 分页的总页数计算
- 当你觉得累的时候!
- [poj] 水题2159
- linux 蓝牙驱动代码阅读笔记
- C++ Const 用法总结
- 舞动的dancing links poj 3740
- FAQ_04_Socket关闭
- Eclipse插件JSEclipse和Aptana的下载和安装
- ListView右击选中项弹出菜单
- Shell之查找与替换
- 红黑树学习
- APN设置方式
- vector的用法
- 先装Linux,后装Windows 如何进入Linux