[JSOI2010]满汉全席 -- 2-SAT

2-SAT快忘了,回忆了一下 x--->y   代表选择x必选择y

[JSOI2010]满汉全席  -- 2-SAT

 

 

#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;
}

  

上一篇:图论算法复习笔记


下一篇:[BZOJ4316]小C的独立集——仙人掌最大独立集