zoukankan      html  css  js  c++  java
  • DLX

    说实话这么奇怪十字的链表结构还能在里面删来恢复,按各种顺序和套路以致把时间复杂度减下来,果然是Knuth !
    主要是计算最小列从n*m变成了m了,这里m是指下面代码的mm

    #include <cstdio>
    #include <memory>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <cassert>
    #include <string>
    #include <ctime>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    #include <cassert>
    #include <iomanip> 
    #include <set>
    #include <iterator>  
    using namespace std;
    #define REP(i,n) for(int i=0;i<n;i++)
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define req(i,a,b) for(int i=a;i>=b;i--)
    #define rp(i,a) for(int i=head[a];i+1;i=edge[i].next)
    #define cl(a,b) memset(a,b,sizeof a);
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mod 10007
    const int inf = ~0u >> 2;
    const ll INF = (1LL << 62) - 1;
    double eps = 1e-12;
    const int N = 505 + 5;
    const int M = 35*35;
    int s[N];
    
    int n, m, k;
    //int a[M][M];
    int b[M*N+M];
    class DLX {
    private:
    	const static int maxn = M*N+M;
    public:
    	int l[maxn], r[maxn], u[maxn], d[maxn], s[M];
    	int row[maxn],col[maxn],head[N];
    	int sz = 0;
    	void init(int n,int mm) {
    		cnt = 0;
    		ans = inf;
    		level = 0;
    		sz = 0;
    		for (int j = 0; j <= mm; j++)
    		{
    			row[j] = 0;
    			col[j] = j;
    			s[j] = 0;
    			l[j] = j - 1;
    			r[j] = j + 1;
    			u[j] = d[j] = j;
    			sz++;
    		}
    		sz--;
    		l[0] = mm;
    		r[mm] = 0;
    		for (int i = 1; i <= n; i++)
    			head[i] = -1;
    	}
    	void remove(int y) {//y is column index
    		r[l[y]] = r[y];
    		l[r[y]] = l[y];
    		for (int i = d[y]; i != y; i = d[i]) {
    			for (int j = r[i]; j != i; j = r[j]) {
    				d[u[j]] = d[j];
    				u[d[j]] = u[j];
    				s[col[j]]--;
    			}
    		}
    	}
    	void resume(int y) {//y is column index
    		for (int i = u[y]; i != y; i = u[i]) {
    			for (int j = l[i]; j != i; j = l[j]) {
    				d[u[j]] = j;
    				u[d[j]] = j;
    				s[col[j]]++;
    			}
    		}
    		l[r[y]] = y;
    		r[l[y]] = y;
    	}
    	void link(int rowIndex, int colIndex) {
    		col[++sz] = colIndex;
    		s[colIndex]++;
    		d[sz] = d[colIndex];
    		u[sz] = colIndex;
    		u[d[sz]] = sz;
    		d[u[sz]] = sz;
    		if (head[rowIndex] == -1)
    		{
    			l[sz] = r[sz] = sz;
    			head[rowIndex] = sz;
    		}
    		else {
    			l[sz] = head[rowIndex];
    			r[sz] = r[head[rowIndex]];
    			l[r[sz]] = sz;
    			r[l[sz]] = sz;
    		}
    		
    	}
    	bool dance() {
    		if (r[0] == 0) {
    			return true;
    		}
    		int minum = r[0];
    		for (int i = r[0]; i != 0; i = r[i]) {
    			if (s[i] < s[minum])
    				minum = i;
    		}
    		if (s[minum] == 0) {
    			return false;
    		}
    
    		level++;
    		if (level >= ans)
    		{
    			level--;
    			return false;
    		}
    		remove(minum);
    
    		for (int i = d[minum]; i != minum; i = d[i]) {
    			for (int j = r[i]; j != i; j = r[j]) {
    				remove(col[j]);
    			}
    			bool flag = dance();
    			for (int j = l[i]; j != i; j = l[j]) {
    				resume(col[j]);
    			}
    			if (flag||level>=ans) {
    				cnt++;
    				ans = min(ans, level);
    				break;
    			}
    		}
    
    		resume(minum);
    		level--;
    
    		return false;
    	}
    	int getAns() {
    		return ans;
    	}
    private:
    	int cnt = 0;
    	int ans = inf;
    	int level = 0;
    }dlx;
    int main() {
    	int t;
    	//std::ios::sync_with_stdio(false);
    	scanf("%d", &t);
    	while (t--) {
    		scanf("%d%d%d", &n, &m, &k);
    		int mm = n*m;
    		dlx.init(k,mm);
    		for (int p = 1; p <= k; p++) {
    			int x, y, xx, yy;
    			scanf("%d%d%d%d", &x, &y, &xx, &yy);
    			
    			for (int i = x + 1; i <= xx; i++)
    			{
    				for (int j = y + 1; j <= yy; j++) {
    					dlx.link(p, (i - 1)*m + j);
    				}
    			}
    		}
    		dlx.dance();
    		printf("%d
    ", dlx.getAns()==inf?-1:dlx.getAns());
    	}
    	return 0;
    }
    
  • 相关阅读:
    继承在WCF中的问题和解决办法
    bootstrap插件学习-bootstrap.dropdown.js
    C#山寨版本拨号客户端
    关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系
    [源码]Literacy 快速反射读写对象属性,字段
    Hadoop Streaming框架学习(一)
    AOP详解
    SESSION会话技术
    mongodb 备份、还原、导入、导出
    Qt 技巧: 解决未解析的SSL问题
  • 原文地址:https://www.cnblogs.com/HaibaraAi/p/6516073.html
Copyright © 2011-2022 走看看