[JSOI2010]满汉全席 -- 2-SAT
2-SAT快忘了,回忆了一下 x--->y 代表选择x必选择y

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<cstdio>
using namespace std;
const int maxn = 100000;
struct Node {
int to;
int next;
}G[maxn];
int head[maxn];
int vis[maxn];
int z;
void add(int be, int en) {
G[++z].to = en;
G[z].next = head[be];
head[be] = z;
}
int n, m;
int get(char *cn) {
int ret = 0;
for (int i = 1; cn[i]; i++) {
if (cn[i] >= '0' && cn[i] <= '9') {
ret *= 10;
ret += cn[i] - '0';
}
else break;
}
return ret;
}
int dfn[maxn], clor[maxn], low[maxn];
int df, ans;
stack<int>s;
int tarjan(int x) {
dfn[x] = low[x] = ++df;
s.push(x);
vis[x] = 1;
for (int i = head[x]; i; i = G[i].next) {
int p = G[i].to;
if (!dfn[p]) {
tarjan(p);
low[x] = min(low[x], low[p]);
}
else if (vis[p]) {
low[x] = min(low[x], dfn[p]);
}
}
if (low[x] == dfn[x]) {
ans++;
while (1) {
int c = s.top();
s.pop();
vis[c] = 0;
clor[c] = ans;
if (c == x) break;
}
}
return 0;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
char a[100];
char b[100];
memset(head, 0, sizeof(head));
memset(clor, 0, sizeof(clor));
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
df = 0;
ans = 0;
z = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i < m; i++) {//m+n,h正
scanf("%s%s", a, b);
int be = get(a);
int en = get(b);
if (a[0] == 'm' && b[0] == 'm') {
add(be, en + n);//h--m
add(en, be + n);//
}
else if (a[0] == 'h' && b[0] == 'h') {
add(be + n, en);
add(en + n, be);
}
else if (a[0] == 'm' && b[0] == 'h') {
add(be, en);
add(en + n, be + n);
}
else if (a[0] == 'h' && b[0] == 'm') {
add(be + n, en + n);
add(en, be);
}
a[0] = 0;
b[0] = 0;
}
for (int i = 1; i <= 2*n; i++) {
if (!dfn[i]) tarjan(i);
}
int flag = 0;
for (int i = 1; i <= n ; i++) {
if (clor[i] == clor[i + n]) {
flag = 1;
break;
}
}
if (!flag) printf("GOOD\n");
else printf("BAD\n");
while (s.size()) s.pop();
}
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号