给n个灯和m个开关, 每个灯可以由若干个开关控制, 每个开关也可以控制若干个灯, 问你能否找到一种开关的状态, 使得所有的灯都亮。
将灯作为列, 然后把每个开关拆成两行, 开是一行, 关是一行。 然后跑一下就可以。 输出路径的话, 就是用一个vis数组记录一下哪些行被访问过。
#include<bits/stdc++.h> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, a, n) for(int i = a; i<n; i++) #define ull unsigned long long typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 1050; const int maxNode = 20000; int num; struct DLX { int L[maxNode], R[maxNode], U[maxNode], D[maxNode], row[maxNode], col[maxNode]; int S[maxn], H[maxn], sz, n, m, vis[maxn*2]; void remove(int c) { for(int i = D[c]; i!=c; i = D[i]) { L[R[i]] = L[i]; R[L[i]] = R[i]; } } void resume(int c) { for(int i = U[c]; i!=c; i = U[i]) { L[R[i]] = i; R[L[i]] = i; } } int dfs(int d) { if(R[0] == 0) { return 1; } int c = R[0]; for(int i = R[0]; i!=0; i = R[i]) if(S[c]>S[i]) c = i; for(int i = D[c]; i!=c; i = D[i]) { if(vis[row[i]^1]) continue; remove(i); vis[row[i]] = 1; for(int j = R[i]; j != i; j = R[j]) remove(j); if(dfs(d+1)) return 1; for(int j = L[i]; j != i; j = L[j]) resume(j); resume(i); vis[row[i]] = 0; } return 0; } void add(int r, int c) { sz++; row[sz] = r; col[sz] = c; S[c]++; U[sz] = U[c]; D[sz] = c; D[U[c]] = sz; U[c] = sz; if(~H[r]) { R[sz] = H[r]; L[sz] = L[H[r]]; L[R[sz]] = sz; R[L[sz]] = sz; } else { H[r] = L[sz] = R[sz] = sz; } } void init() { mem1(H); for(int i = 0; i<=n; i++) { R[i] = i+1; L[i] = i-1; U[i] = i; D[i] = i; } mem(S); R[n] = 0; L[0] = n; sz = n; } void solve() { init(); mem(vis); int x, y; char s[4]; for(int i = 1; i <= n; i++) { scanf("%d", &x); while(x--) { scanf("%d%s", &y, s); if(s[1] == 'N') { add(y<<1, i); } else { add(y<<1|1, i); } } } if(dfs(0)) { for(int i = 1; i <= m-1; i ++) { if(vis[i<<1]) { printf("ON "); } else { printf("OFF "); } } if(vis[2*m]) { puts("ON"); } else { puts("OFF"); } } else { puts("-1"); } } }dlx; int main() { while(~scanf("%d%d", &dlx.n, &dlx.m)) { dlx.solve(); } return 0; }