Source: Light OJ 1251 Forming the Council
Test instructions: A number of conditions satisfy at least one of the number of people left behind in any possible scheme output
Idea: 2-sat basic problem
#include <cstdio> #include <cstring> #include <vector> using namespace std;
const int MAXN = 100010;
int n, m;
Vector <int> G[maxn*2];
BOOL Mark[maxn*2];
int s[maxn*2], C;
int A[MAXN], b[maxn], sum;
int ANS[MAXN];
bool Dfs (int x) {if (mark[x^1]) return false;
if (Mark[x]) return true;
Mark[x] = true;
S[c++] = x;
for (int i = 0; i < g[x].size (); i++) if (!dfs (G[x][i])) return false;
return true;
} void Init () {for (int i = 0; i < n*2; i++) g[i].clear ();
memset (mark, 0, sizeof (Mark));
} void Addedge (int u, int v, int x, int y) {u = u * 2 + x;
v = v * 2 + y;
G[u].push_back (v^1);
G[v].push_back (u^1);
} bool Solve () {for (int i = 0; i < n*2; i + = 2) {if (!mark[i] &&!mark[i+1]) {c = 0;
if (!dfs (i)) {while (C > 0) mark[s[--c]] = false;
if (!dfs (i+1)) return false;
}}} return true;
} int Get (char *s) {int ans = 0;
for (int i = 1; s[i]; i++) ans = ans * + s[i]-' 0 '; return ans;
} int main () {int cas = 1;
int T;
scanf ("%d", &t);
while (t--) {scanf ("%d%d", &m, &n);
Init ();
while (m--) {char s1[100], s2[100];
scanf ("%s%s", S1, S2);
int u = Get (S1);
int v = GET (S2);
u--;
v--;
int x, y;
if (s1[0] = = ' + ') x = 1;
else x = 0;
if (s2[0] = = ' + ') y = 1;
else y = 0;
Addedge (U, V, x^1, y^1);
} if (!solve ()) {printf ("Case%d:no\n", cas++);
Continue
} int l = 0;
for (int i = 0; i < n; i++) if (mark[i*2+1]) ans[l++] = i;
printf ("Case%d:yes\n", cas++);
printf ("%d", l);
for (int i = 0; i < l; i++) printf ("%d", ans[i]+1);
Puts ("");
} return 0; }