Pagini recente » Cod sursa (job #1786038) | Cod sursa (job #25893) | Cod sursa (job #279775) | Cod sursa (job #2587754) | Cod sursa (job #1758901)
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#define NMax 100000
using namespace std;
vector<int> v[2*NMax+500];
vector<int> v_m[2*NMax+500]; //mirror of v
vector<int> comp_nodes[NMax+100];
bool comp_val[NMax+100];
int comp[2*NMax+200];
int sol[2*NMax+200];
int viz[2*NMax+200];
int n, m;
#define v (v+NMax)
#define v_m (v_m+NMax)
#define viz (viz+NMax)
#define comp (comp+NMax)
#define sol (sol+NMax)
#define DEBUG false
void kosaraju_visit (int nod, vector<int> &q) {
if (viz[nod]) return;
viz[nod] = true;
for (int i = 0; i < v[nod].size (); i++)
kosaraju_visit(v[nod][i], q);
q.push_back (nod);
}
void kosaraju_assign (int nod, int component) {
if (comp[nod] != 0) return;
//if (DEBUG) cout << nod << ' ';
// node is not assigned -> assign it to current component
comp[nod] = component;
comp_nodes[component].push_back (nod);
for (int i = 0; i < v_m[nod].size (); i++) {
kosaraju_assign(v_m[nod][i], component);
}
}
bool twosat () {
vector<int> q;
for (int i = -n; i <= n; i++) {
if (i==0) continue;
kosaraju_visit (i, q);
}
int nrc = 0; //number of components
for (int i = q.size () - 1; i >= 0; i--) {
int nod = q[i];
if (DEBUG) cout << nod << " " << comp[nod] << " ";
if (comp[nod] == 0) {
if (DEBUG) cout << "entered";
kosaraju_assign(nod, ++nrc);
if (DEBUG) cout << '\n';
comp_val[nrc] = 0;
}
if (DEBUG) cout << '\n';
}
if (!DEBUG) goto end_log;
cout << "Number of components: " << nrc << '\n';
cout << "queue: ";
for (int i = 0; i < q.size (); i++)
cout << q[i] << ' ';
cout << '\n';
for (int i = 1; i <= n; i++) {
cout << i << ' ' << comp[i] << ' ' << comp[-i] << '\n';
}
end_log:
//assert a player and it's negation are not in the same component
for (int i = 1; i <= n; i++) {
if (comp[i] == comp[-i])
return false;
}
if (DEBUG) cout << "Start assigning!\n";
for (int i = 1; i <= nrc; i++) {
for (int j = 0; j < comp_nodes[i].size (); j++) {
int nod = comp_nodes[i][j];
//assign solution to node
sol[nod] = comp_val[i];
// assign opposite value to component of the negation
comp_val[comp[-nod]] = 1 - comp_val[i];
}
}
if (DEBUG) cout << "Finished twosat\n";
return true;
}
int main ()
{
ifstream fin ("2sat.in");
ofstream fout ("2sat.out");
fin >> n >> m;
for (int i = 0; i < m; i++) {
int x, y;
fin >> x >> y;
v[-x].push_back(y);
v[-y].push_back(x);
// mirror
v_m[y].push_back (-x);
v_m[x].push_back (-y);
}
if (twosat()) {
for (int i = 1; i <= n; i++) {
fout << sol[i] << ' ';
}
}
else {
fout <<-1<< '\n';
}
return 0;
}