Cod sursa(job #498770)

Utilizator vlad_DVlad Dumitriu vlad_D Data 6 noiembrie 2010 05:41:28
Problema 2SAT Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <cstdio>
#include <vector>

using namespace std;

#define vii vector<vector<int> >
#define vi vector<int>
#define pb(a) push_back(a)

int N; // 2 * N (si negativele)
vii G, GT; // Grafu implicatiilor si transpusu
vi val; // valorile la sfarsit
vi st, viz; // stack si vizitat
int no_sol; // daca nu este solutie

inline int neg(int n) { // negatu
	return (n <= N) ? (N + n) : (n - N);
}
inline void sau(int a, int b) {
	// transforma in implicatii
	G[neg(a)].pb(b); G[neg(b)].pb(a);
	GT[b].pb(neg(a)); GT[a].pb(neg(b));
}
inline void dfs(int nod) {
	viz[nod] = 1;
	for (int i = 0; i < G[nod].size(); ++i) {
		int nod2 = G[nod][i];
		if (!viz[nod2]) dfs(nod2);
	}
	st.pb(nod);
}
inline void dfs_t(int nod) {
	viz[nod] = 1;
	if (val[nod]) no_sol = 1; // nu e solutie
	val[nod] = 0; val[neg(nod)] = 1;
	for (int i = 0; i < GT[nod].size(); ++i) {
		int nod2 = GT[nod][i];
		if (!viz[nod2]) dfs_t(nod2);
	}	
}
int two_sat() {
	viz.assign(2*N+1, 0);
	for (int i = 1; i <= 2 * N; ++i) if (!viz[i])
		dfs(i);
	viz.assign(2*N+1, 0);
	for (int i = st.size() - 1; i >= 0; --i) 
		if (!viz[st[i]] && !viz[neg(st[i])])
			dfs_t(st[i]);
	return no_sol == 0;
}
int main() {
	freopen("2sat.in", "r", stdin);
	freopen("2sat.out", "w", stdout);
	int M;
	scanf("%d %d", &N, &M);
	G.resize(2 * N + 1); GT.resize(2*N+1);
	val.resize(2*N+1);
	while (M--) {
		int a, b;
		scanf("%d %d", &a, &b);
		if (a < 0) a = neg(-a);
		if (b < 0) b = neg(-b);
		sau(a, b);
	}
	if (two_sat()) {
		for (int i = 0; i < N; ++i) printf("%d ", val[i]);
	
	} else printf("-1\n");
}