您的位置:首页 > 其它

hust 1017 dancing links

2013-12-22 15:47 190 查看
开始学习dancing links了,01矩阵覆盖,居然搞了一中午+半个下午。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 22
#define MAXN 100005
#define mod 1000007
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
#define N 1005
#define M N*N
int U[M],D[M],L[M],R[M];
int ID[M],row[M],S
,ans
;
int k_ans;
void remove(int c)
{
	int i,j;
	L[R[c]]=L[c];
	R[L[c]]=R[c];
	for(i=D[c];i!=c;i=D[i]){
		for(j=R[i];j!=i;j=R[j]){
			U[D[j]]=U[j];
			D[U[j]]=D[j];
			S[ID[j]]--;
		}
	}
}
void resume(int c)
{
	int i,j;
	for(i=U[c];i!=c;i=U[i]){
		for(j=L[i];j!=i;j=L[j]){
			U[D[j]]=D[U[j]]=j;
			S[ID[j]]++;
		}
	}
	R[L[c]]=L[R[c]]=c;
}
void init(int n,int m)
{
    memset(S,0,sizeof(S));
    for(int i=1;i<=m;i++)
    {
        U[i]=D[i]=L[i+1]=R[i-1]=i;
    }
    R[m]=0;
}
bool dfs(int k)
{
  //  printf("%d\n",k);
    if(!R[0]) {k_ans=k;return true;}
    int tmp,mins=0x7fffffff;
    for(int i=R[0];i;i=R[i])
    {
        if(S[i]<mins)
        {
            mins=S[i];
            tmp=i;
        }
    }
    remove(tmp);
    for(int i=D[tmp];i!=tmp;i=D[i]) //选row[i]行
    {
        for(int j=R[i];j!=i;j=R[j])
        {
            remove(ID[j]);
        }
        ans[k]=row[i];
        if(dfs(k+1)) return true;
        for(int j=L[i];j!=i;j=L[j])
        {
            resume(ID[j]);
        }
    }
    resume(tmp);
    return false;
}
int main()
{
    int n,m,k,a,top,base;
    while(~scanf("%d%d",&n,&m))
    {
        init(n,m);
        top=m+1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&k);
            for(int j=1;j<=k;j++)
            {
                scanf("%d",&a);
                S[a]++;
                ID[top]=a;row[top]=i;

                U[top]=U[a];D[U[a]]=top;    //插入列
                U[a]=top;D[top]=a;

                if(j==1) {L[top]=R[top]=top;base=top;}  //插入行
                else
                {
                    L[top]=L[base];R[L[base]]=top;
                    L[base]=top;R[top]=base;
                }
                top++;
            }
        }
        if(dfs(0))
        {
            printf("%d",k_ans);
            for(int i=0;i<k_ans;i++) printf(" %d",ans[i]);
            puts("");
        }
        else puts("NO");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: