Pagini recente » Cod sursa (job #929186) | Cod sursa (job #2905557) | Cod sursa (job #1907696) | Cod sursa (job #2111872) | Cod sursa (job #2447362)
#include<vector>
#include<fstream>
#include<iostream>
#include<stack>
#include<queue>
#define N 200005
using namespace std;
int n,m,disc[N],low[N],In_stack[N],scc,comp[N],in_deg[N],val[N];
vector<int> G[N],sol[N];
stack<int> S;
void read()
{
int x,y;
ifstream fin("2sat.in");
fin>>n>>m;
for(int i=1;i<=m;i++)
{
fin>>x>>y;
if(x>0 && y>0)
{G[x+n].push_back(y);
G[y+n].push_back(x);
}
else
if(x>0 && y<0)
{
G[x+n].push_back(n-y);
G[-y].push_back(x);
}
else
if(x<0 && y>0)
{
G[-x].push_back(y);
G[y+n].push_back(n-x);
}
else
{
G[-x].push_back(n-y);
G[-y].push_back(n-x);
}
}
fin.close();
}
void Tarjan(int u,int &time)
{
disc[u]=low[u]=++time;
S.push(u);
In_stack[u]=1;
vector<int>::iterator it;
for(it=G[u].begin();it!=G[u].end();it++)
{
int v=*it;
if(!disc[v])
{
Tarjan(v,time);
low[u]=min(low[u],low[v]);
}
else
if(In_stack[v])
low[u]=min(low[u],disc[v]);
}
if(low[u]==disc[u])
{
int w=0;
++scc;
while(S.top()!=u)
{
sol[scc].push_back(S.top());
In_stack[S.top()]=0;
comp[S.top()]=scc;
S.pop();
}
sol[scc].push_back(u);
comp[u]=scc;
In_stack[u]=0;
S.pop();
}
}
queue<int> q;
void solve()
{
int start=0,satisfiable=1,x;
for(int i=1;i<=2*n;i++)
if(!disc[i])
Tarjan(i,start);
for(int i=1;i<=n && satisfiable;i++)
if(comp[i]==comp[i+n])
satisfiable=0;
for(int i=1;i<=n;i++)
val[i]=-1;
//Toate nodurile dintr-o componenta tare-conexa au aceeasi valoare de adevar
ofstream fout("2sat.out");
if(satisfiable)
{
for(int i=1;i<=2*n;i++)
{
vector<int>::iterator it;
for(it=G[i].begin();it!=G[i].end();it++)
if(comp[i]!=comp[*it])
in_deg[comp[*it]]++;
}
//Algoritmul lui Tarjan realizeaza o sortare topologica in ordine inversa,deci ultima
//componenta tare conexa va avea gradul interior asociat 0
for(int i=1;i<=scc;i++)
if(!in_deg[i])
q.push(i);
//cout<<q.front();
while(!q.empty())
{
x=q.front();
q.pop();
vector<int>::iterator it,it2;
for(it=sol[x].begin();it!=sol[x].end();it++)
{
int change=((*it)>n )? (*it)-n : *it;
//din pacate nu identificam si componenta "negatie" din noul graf format din componentele tare conexe ce devin noduri
//if(val[change]==-1)
{
//cout<<(*it)<<' ';
if((*it)>n)
val[change]=1;
else
val[change]=0;
}
}
for(it=sol[x].begin();it!=sol[x].end();it++)
for(it2=G[*it].begin();it2!=G[*it].end();it2++)
{
if(comp[*it2]!=comp[*it])
{
--in_deg[comp[*it2]];
if(in_deg[*it2]==0) q.push(comp[*it2]);
}
}
}
for(int i=1;i<=n;i++)
fout<<val[i]<<' ';
}
else
fout<<"-1";
fout.close();
}
int main()
{
read();
solve();
}