P4929 【模板】舞蹈链(DLX)

https://www.luogu.com.cn/problem/solution/P4929

/*

*/
/*
3 3
1 0 1
1 1 0
0 1 1

No Solution!

3 3
0 0 1
1 0 0
0 1 0

2 1 3

*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=5e2 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

struct dlx{
    int col,row;
    int lft,rht,up,dn;
}node[6000];
int roww[maxn],lcnt[maxn],cnt;
int n,m,ans[maxn];

void init()
{
    for(int i=0;i<=m;i++)
    {
        node[i].lft=i-1;
        node[i].rht=i+1;
        node[i].up=i;
        node[i].dn=i;
        lcnt[i]=0;//-------------------------miss
    }
    node[0].lft=m;
    node[m].rht=0;
    cnt=m;
}

void addnode(int r,int c)
{
    node[++cnt].row=r;
    node[cnt].col=c;
    node[cnt].up=node[c].up;///-------------not dn
    node[cnt].dn=c;
    node[node[c].up].dn=cnt;//---------------not dn
    node[c].up=cnt;
    if(roww[r])
    {
        node[cnt].lft=node[roww[r]].lft;//---------not .rht
        node[cnt].rht=roww[r];
        node[node[roww[r]].lft].rht=cnt;//
        node[roww[r]].lft=cnt;          //order
    }
    else{
        roww[r]=cnt;
        node[cnt].lft=cnt;
        node[cnt].rht=cnt;
    }
    lcnt[c]++;
}

void remove(int c)
{
    for(int i=node[c].dn;i!=c;i=node[i].dn)
    {
        for(int j=node[i].rht;j!=i;j=node[j].rht)
        {
            node[node[j].up].dn=node[j].dn;
            node[node[j].dn].up=node[j].up;
            lcnt[node[j].col]--;
        }
    }
    node[node[c].lft].rht=node[c].rht;
    node[node[c].rht].lft=node[c].lft;
}
void resume(int c)
{
    for(int i=node[c].dn;i!=c;i=node[i].dn)
    {
        for(int j=node[i].rht;j!=i;j=node[j].rht)
        {
            node[node[j].up].dn=j;
            node[node[j].dn].up=j;
            lcnt[node[j].col]++;
        }
    }
    node[node[c].lft].rht=c;
    node[node[c].rht].lft=c;
}

bool dance(int dep)
{
    if(node[0].rht==0){
        for(int i=1;i<=dep-1;i++)    
            cout<<ans[i]<<" ";
        return true;
    }
    int C=node[0].rht;
    for(int i=node[0].rht;i!=0;i=node[i].rht)
    {
        if(lcnt[C]>lcnt[i])
            C=i;
    }
    remove(C);
    for(int i=node[C].dn;i!=C;i=node[i].dn)
    {
        ans[dep]=node[i].row;
        for(int j=node[i].rht;j!=i;j=node[j].rht)
            remove(node[j].col);    
        if(dance(dep+1)) return true;
        for(int j=node[i].rht;j!=i;j=node[j].rht)
            resume(node[j].col);
    }
    resume(C);
    return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    init();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            int tmp;cin>>tmp;
            if(tmp) addnode(i,j);
        }
    
    if(dance(1)==0) cout<<"No solution!\n";
    
    return 0;
}

 

posted @ 2023-11-08 09:43  JMXZ  阅读(9)  评论(0)    收藏  举报