[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
题意:就是给你一个随机的九宫格,问你答案是多少?
算法: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 }
题意:给你一个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 }
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 }
题意:就是经典问题:给你一堆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; }
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 }
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 }
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 }
对了,有一个更快捷的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 }
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 }
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 }
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 }
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 }