dancelinks (精确) 模板

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define maxm 1010*1010
#define maxn 1010

int R[maxm],L[maxm],U[maxm],D[maxm],col[maxm],row[maxm],sz;
int S[maxn];
int deep,ans[1500];
void Exaxt_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 Exaxt_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[j]];
                     U[D[j]] = j;
                     D[U[j]] = j;
             }
        }
        L[R[c]] = c;
     R[L[c]] = c;
}
bool dfs() {
  if(R[0] == 0) {
          return true;
     }
        int i , j , idx , MM = 999999;
   for(i = R[0];i != 0 ; i = R[i]) {
                if(S[i] < MM) {
                   MM = S[i];
                       idx = i;
         }
        }
        Exaxt_remove(idx);
       for(i = D[idx]; i != idx; i = D[i]) {
            ans[deep++] = row[i];
            for(j = R[i]; j != i ; j = R[j]) {
                       Exaxt_remove(col[j]);
            }
                if(dfs())
                {
                        return true;
             }
                deep--;
          for(j = L[i]; j != i ; j = L[j]) {
                       Exaxt_resume(col[j]);
            }
        }
        Exaxt_resume(idx);
       return false;
}
void Insert(int i , int j, int &first) {// 行数i通常用不到
  if(first == -1) {
                first = sz;
      }
        L[sz] = sz - 1;
  R[sz] = sz + 1;
  D[sz] = j;
       D[U[j]] = sz;
    U[sz] = U[j];
    U[j] = sz;
       col[sz] = j;
     row[sz] = i;
     S[j] ++;
 sz ++;
}
void init(int n) {//列数
      sz = 0;
  for(int i = 0 ; i <= n ; i ++) {
          U[i] = i;
                D[i] = i;
                L[i] = i - 1;
            R[i] = i + 1;
    }
        L[0] = n;
        R[n] = 0;
        sz = n + 1;
      memset(S,0,sizeof(S));
}


int mat[1010][1010];
int main()
{
 int n,m;
 while(~scanf("%d%d",&n,&m))
      {
                memset(mat,0,sizeof(mat));
               init(m);
         deep = 0;
                for(int i=1;i<=n;i++)
             {
                        int x,y;
                 scanf("%d",&x);
                  while(x--)
                       {
                                scanf("%d",&y);
                          mat[i][y] = 1;
                   }
                }
                for(int i=1;i<=n;i++)
             {
                        int first = -1;
                  for(int j=1; j<=m; j++)
                   {
                                //printf(" %d",mat[i][j]);
                               if(mat[i][j])
                            Insert(i,j,first);
                       }
                        //puts("");
                      //printf("%d==\n",sz);
                   if(first != -1)
                  {
                                R[sz-1] = first;
                         L[first] = sz-1;
                 }
                }
                if(!dfs())
               {
                        puts("NO");
              }
                else
             {
                        printf("%d",deep);
                       for(int i=0;i<deep;i++)
                   {
                                printf(" %d",ans[i]);
                    }
                        puts("");
                }
        }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值