Pagini recente » Cod sursa (job #426401) | Cod sursa (job #925406) | Cod sursa (job #455313) | Cod sursa (job #2399742) | Cod sursa (job #372181)
Cod sursa(job #372181)
#include <fstream>
#include <vector>
#include <stack>
#include <cstring>
#define MAXN 100010
using namespace std;
ifstream fi("2sat.in");
ofstream fo("2sat.out");
int N,M;
vector< int > G[2][MAXN]; // G[0] - graf normal , G[1] - graf transpus
vector< int > GComp[MAXN]; // graful componentelor tare conexe
int WhatComp[MAXN],used[MAXN],NComps,usedComp[MAXN],assoc[MAXN],val[MAXN];
stack< int > S;
vector< vector< int > > Comps;
//introducem in graf o restrictie de tipul x sau y
//N-x+1 = ~x
void make_graph(int x, int y){
G[0][N-x+1].push_back(y);
G[1][y].push_back(N-x+1);
G[0][N-y+1].push_back(x);
G[1][x].push_back(N-y+1);
}
void get_input(){
int x,y,z;
fi>>N>>M;
N*=2;
for (int i=1; i<=M; ++i){
fi>>x>>y>>z;
if (x<0) { x=-x; x=N-x+1; }
if (y<0) { y=-y; y=N-y+1; }
make_graph(x, y);
}
fi.close();
}
//parcurgerea +
void DFSPlus(int nod, vector<int>* G){
used[nod]=1;
vector<int>::iterator it;
for (it=G[nod].begin(); it!=G[nod].end(); ++it)
if (!used[*it]) DFSPlus(*it, G);
S.push(nod);
}
//parcurgerea -
void DFSMinus(int nod, vector<int>* G, int componenta){
WhatComp[nod]=componenta;
vector<int>::iterator it;
for (it=G[nod].begin(); it!=G[nod].end(); ++it)
if (!WhatComp[*it]) DFSMinus(*it, G, componenta);
}
//sortare topologica
void topologica(int nod, vector<int>* G){
used[nod]=1;
vector<int>::iterator it;
for (it=G[nod].begin(); it!=G[nod].end(); ++it)
if (!used[*it]) topologica(*it, G);
S.push(nod);
}
void get_output(){
N/=2;
for (int i=1; i<N; ++i) fo<<val[i]<<" ";
fo<<val[N]<<"\n";
fo.close();
}
int main(){
get_input();
//determin componentele tare conexe
memset(used, 0, sizeof(used));
memset(WhatComp, 0, sizeof(WhatComp));
for (int i=1; i<=N; ++i) if (!used[i]) DFSPlus(i, G[0]);
NComps=0;
while (!S.empty()){
if (!WhatComp[S.top()]){ ++NComps; DFSMinus(S. top(),G[1],NComps); }
S.pop();
}
Comps.resize(NComps+1);
for (int i=1; i<=N; ++i) Comps[WhatComp[i]].push_back(i);
//verific daca am solutie
for (int i=1; i<=N; ++i) if (WhatComp[i]==WhatComp[N-i+1]){
fo<<"-1\n";fo.close(); return 0;
}
//construiesc DAG-ul componentelor tare conexe
for (int i=1; i<=N; ++i){
memset(usedComp, 0, sizeof(usedComp));
for (vector<int>::iterator it=G[0][i].begin(); it!=G[0][i].end(); ++it)
if (WhatComp[i]!=WhatComp[*it] && !usedComp[WhatComp[*it]]){
GComp[WhatComp[i]].push_back(WhatComp[*it]);
usedComp[WhatComp[*it]]=1; // sa nu adaug acelasi vecin de 2 ori
}
}
for (int i=1; i<=N; ++i) assoc[WhatComp[i]]=WhatComp[N-i+1]; // formez perechile de componente tare conexe
//sortez DAG-ul topologic
memset(used, 0, sizeof(used));
for (int i=1; i<=NComps; ++i)
if (!used[i]) topologica(i,GComp);
//caut solutia
memset(used, 0, sizeof(used));
memset(val, 0, sizeof(val));
while (!S.empty()){
if (!used[S.top()]){
for (vector<int>::iterator it=Comps[S.top()].begin(); it!=Comps[S.top()].end(); ++it) { val[*it]=0; val[N-(*it)+1]=1; }
used[S.top()]=1;
used[assoc[S.top()]]=1;
}
S.pop();
}
get_output();
return 0;
}