Pagini recente » Cod sursa (job #498951) | Cod sursa (job #2504055) | Cod sursa (job #512503) | Monitorul de evaluare | Cod sursa (job #3353769)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("2sat.in");
ofstream fout("2sat.out");
int n, m;
vector<vector<int>> graf, graf_T, comps;
vector<int> visited, scc, ans;
stack<int> out;
vector<int> comp;
// memorize negations helpers
int repr_mem(int x) {
if(x < 0)
return x * (-1) + n;
else
return x;
}
int repr_neg(int x) {
if (x > n)
return (x - n) * (-1);
else
return x;
}
int negate_mem(int x) {
x = repr_neg(x);
x *= -1;
return repr_mem(x);
}
// read and construct graf
void read() {
fin >> n >> m;
// allocate memory
graf.assign(2 * n + 1, {});
graf_T.assign(2 * n + 1, {});
visited.assign(2 * n + 1, 0);
comp.assign(2 * n + 1, 0);
ans.assign(2 * n + 1, 0);
for (int i = 0; i < m; i++) {
int x, y;
fin >> x >> y;
x = repr_mem(x);
y = repr_mem(y);
graf[negate_mem(x)].push_back(y);
graf[negate_mem(y)].push_back(x);
// cout << negate_mem(x) << ' ' << y << ' ';
// cout << negate_mem(y) << ' ' << x << '\n';
// construct transpose for kosaraju
graf_T[y].push_back(negate_mem(x));
graf_T[x].push_back(negate_mem(y));
}
}
// dfs in normal
void dfs(int x)
{
visited[x] = 1;
for(auto &next:graf[x]) {
if(!visited[next])
dfs(next);
}
out.push(x);
}
// dfs in trans
void dfs_trans(int x)
{
visited[x] = 1;
scc.push_back(x);
for(auto &next:graf_T[x]) {
if(!visited[next])
dfs_trans(next);
}
}
void kosaraju() {
for(int i = 1; i <= 2 * n; i++)
if(!visited[i])
dfs(i);
fill(visited.begin(), visited.end(), 0);
while(!out.empty()) {
int curr = out.top();
out.pop();
if(visited[curr])
continue;
dfs_trans(curr);
comps.push_back(scc);
scc.clear();
}
// node - component hash map
int idx = 0;
for(auto &scc : comps) {
for(auto &x:scc) {
comp[x] = idx;
}
idx += 1;
}
}
bool sat() {
// check for x an ~x
for(int i = 1; i <= n; i++) {
if(comp[i] == comp[i + n]) {
return false;
}
}
// assignment
for(int i = 1; i <= n; i++) {
ans[i] = (comp[i] > comp[i + n]);
}
return true;
}
int main() {
read();
kosaraju();
cout << "----SCCS----\n" << comps.size() << '\n';
for(auto &scc : comps) {
for(auto &x:scc)
cout << x << ' ';
cout << '\n';
}
if(sat()) {
for(int i = 1; i <= n; i++) {
fout << ans[i] << ' ';
}
}
else {
fout << -1;
}
return 0;
}