2 2 2 1 ON 2 ON 1 1 OFF 2 1 1 1 ON 1 1 OFF
OFF ON -1
转换为01矩阵,dlx重复覆盖
#include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const ll maxn = 1005; int n, m, x, y, T; char s[maxn]; vector<int> f[maxn][2]; inline void read(int &ret) { char c; do { c = getchar(); } while (c < '0' || c > '9'); ret = c - '0'; while ((c = getchar()) >= '0' && c <= '9') ret = ret * 10 + (c - '0'); } struct DLX { #define maxn 10005 #define F(i,A,s) for (int i=A[s];i!=s;i=A[i]) int L[maxn], R[maxn], U[maxn], D[maxn]; int row[maxn], col[maxn], ans[maxn], cnt[maxn]; int n, m, num, sz; bool Flag; void add(int now, int l, int r, int u, int d, int x, int y) { L[now] = l; R[now] = r; U[now] = u; D[now] = d; row[now] = x; col[now] = y; } void reset(int n, int m) { Flag = false; this->n = n; this->m = m; for (int i = 0; i <= m; i++) { add(i, i - 1, i + 1, i, i, 0, i); cnt[i] = 0; } L[0] = m; R[m] = 0; sz = m + 1; } void insert(int x, int y) { int ft = sz - 1; if (row[ft] != x) { add(sz, sz, sz, U[y], y, x, y); U[D[sz]] = sz; D[U[sz]] = sz; } else { add(sz, ft, R[ft], U[y], y, x, y); R[L[sz]] = sz; L[R[sz]] = sz; U[D[sz]] = sz; D[U[sz]] = sz; } ++cnt[y]; ++sz; } //精确覆盖 void remove(int now) { R[L[now]] = R[now]; L[R[now]] = L[now]; F(i,D,now) F(j,R,i) { D[U[j]] = D[j]; U[D[j]] = U[j]; --cnt[col[j]]; } } void resume(int now) { F(i,U,now) F(j,L,i) { D[U[j]] = j; U[D[j]] = j; ++cnt[col[j]]; } R[L[now]] = now; L[R[now]] = now; } int dfs(int x) { if (!R[0]) return 1; int now = R[0]; F(i,R,0) if (cnt[now]>cnt[i]) now = i; remove(now); F(i,D,now) { ans[x] = row[i]; F(j,R,i) remove(col[j]); if (dfs(x + 1)) return 1; F(j,L,i) resume(col[j]); } resume(now); return 0; } //精确覆盖 //重复覆盖 void Remove(int now) { F(i,D,now) { L[R[i]]=L[i]; R[L[i]]=R[i]; } } void Resume(int now) { F(i,U,now) L[R[i]]=R[L[i]]=i; } int vis[maxn]; int flag[maxn]; int A() { int dis=0; F(i,R,0) vis[i]=0; F(i,R,0) if (!vis[i]) { dis++; vis[i]=1; F(j,D,i) F(k,R,j) vis[col[k]]=1; } return dis; } bool Dfs(int x) { if (!R[0]) {num=min(num,x); return true;} else //if (x+A()<num) { int now=R[0]; F(i,R,0) if (cnt[now]>cnt[i]) now = i; F(i,D,now) if (!flag[row[i]^1]) { ans[x]=row[i]; Remove(i);F(j,R,i) Remove(j); flag[row[i]]=1; if (Dfs(x+1)) return true; flag[row[i]]=0; F(j,L,i) Resume(j);Resume(i); } } return false; } void display() { memset(vis,0,sizeof(vis)); for (int i=0;i<num;i++) vis[ans[i]>>1]=ans[i]&1; for (int i=1;i+i<n;i++) { if (vis[i]) printf("ON"); else printf("OFF"); if (i+i==n-1) printf("\n"); else printf(" "); } } void mul() { memset(flag,0,sizeof(flag)); num=0x7FFFFFFF; } //重复覆盖 }dlx; int main() { //read(T); while (~scanf("%d%d",&n,&m)) { dlx.reset(m+m+1,n); for (int i=1;i<=m;i++) { f[i][0].clear(); f[i][1].clear(); } for (int i=1;i<=n;i++) { scanf("%d",&x); while (x--) { scanf("%d%s",&y,s); if (s[1]=='N') f[y][0].push_back(i); else f[y][1].push_back(i); } } for (int i=1;i<=m;++i) for (int j=0;j<2;++j) for (int k=0;k<f[i][j].size();++k) dlx.insert(i+i-j+1,f[i][j][k]); dlx.mul(); if (dlx.Dfs(0)) dlx.display(); else printf("-1\n"); } return 0; }