Pagini recente » Istoria paginii runda/26_februarie_simulare_oji_2024_clasele_11_12 | Cod sursa (job #85001) | Cod sursa (job #2887278) | Cod sursa (job #1080411) | Cod sursa (job #2672812)
#include <bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define fi first
#define se second
#define inf (INT_MAX/2-1)
#define infl (1LL<<60)
#define vi vector<int>
#define vl vector<ll>
#define pb push_back
#define sz(a) (int)(a).size()
#define all(a) begin(a),end(a)
#define y0 y5656
#define y1 y7878
#define aaa system("pause");
#define dbg(x) cerr<<(#x)<<": "<<(x)<<'\n',aaa
#define dbga(x,n) cerr<<(#x)<<"[]: ";for(int _=0;_<n;_++)cerr<<x[_]<<' ';cerr<<'\n',aaa
#define dbgs(x) cerr<<(#x)<<"[stl]: ";for(auto _:x)cerr<<_<<' ';cerr<<'\n',aaa
#define dbgp(x) cerr<<(#x)<<": "<<x.fi<<' '<<x.se<<'\n',aaa
#define maxn 100000
#define maxm 200000
using namespace std;
ifstream fin ("2sat.in");
ofstream fout ("2sat.out");
vi g[2*maxm+5], gt[2*maxm+5], gn[2*maxm+5];
int indeg[2*maxm+5], v[2*maxm+5]; ///indeg = doar pt gn, v = valorile nodurilor
int comp[2*maxm+5]; ///comp = din ce ctc face parte ???
bool viz[2*maxm+5];
void ad (int x, int y) {
g[x].pb(y);
gt[y].pb(x);
}
int oth (int m, int x) {
if (x <= m) return x+m;
return x-m;
}
///trebuie sa scap de "cicli" sau componente tare conexe unde nu am nod cu indeg == 0.
///toate nodurile dintr-o ctc au aceeasi valoare. ulterior, dupa unificarea tuturor
///ctc-urilor in cate un singur nod fiecare, voi ramane cu un DAG, pe care pot face
///sortare topologica
vector<vi> ctc (int m) { ///returneaza vectori de componente
vi preord;
int i;
function<void(int)> df = [&] (int nod) {
viz[nod] = 1;
for (int nn: g[nod])
if (!viz[nn]) df(nn);
preord.pb(nod);
};
for (i = 1; i <= 2*m; i++)
if (!viz[i]) df(i);
fill(viz+1, viz+2*m+1, 0);
int now = 1;
vector<vi> ret(1);
function<void(int)> dft = [&] (int nod) {
viz[nod] = 1;
ret.back().pb(nod);
comp[nod] = now;
for (int nn: gt[nod])
if (!viz[nn]) dft(nn);
};
for (i = 2*m-1; i >= 0; i--)
if (!viz[preord[i]]) {
ret.pb(vi());
dft(preord[i]);
now++;
}
return ret;
}
int main () {
int n, m; fin >> m >> n;
int i, a, b;
vector<pii> input;
for (i = 1; i <= n; i++) {
fin >> a >> b;
input.pb(pii(0, a));
if (a < 0) input.back().fi = 1;
input.pb(pii(0, b));
if (b < 0) input.back().fi = 1;
if (a > 0 && b > 0) {
ad(m+a, b); ///!a => b
ad(m+b, a); ///!b => a
} else if (a > 0 && b < 0) {
ad(m+a, m+abs(b)); ///!a => !b
ad(abs(b), a); ///b => a
} else if (a < 0 && b > 0) {
ad(abs(a), b); ///a => b
ad(m+b, m+abs(a)); ///!b => !a
} else {
ad(abs(a), m+abs(b)); ///a => !b
ad(abs(b), m+abs(a)); ///b => !a
}
}
vector<vi> div = ctc(m); ///div = diviziune graf in ctc
int numc = sz(div)-1;
for (i = 1; i <= 2*m; i++)
for (int x: g[i])
if (comp[i] != comp[x]) {
gn[comp[i]].pb(comp[x]);
indeg[comp[x]]++;
}
///acum lucrezi pe gn
queue<int> qu;
for (i = 1; i <= numc; i++)
if (indeg[i] == 0) qu.push(i);
fill(v+1, v+2*m+1, -1);
while (!qu.empty()) {
int nod = qu.front(); qu.pop();
for (int x: div[nod]) { ///pt fiecare nod efectiv din diviziune
if (v[x] == -1) v[x] = 0;
if (v[oth(m, x)] == -1) v[oth(m, x)] = 1;
}
for (int nn: gn[nod]) {
indeg[nn]--;
if (indeg[nn] == 0) qu.push(nn);
}
}
for (i = 1; i <= 2*m; i++)
if (v[i] == -1 && v[oth(m, i)] != -1) v[i] = v[oth(m, i)] ^ 1;
for (i = 1; i <= 2*m; i++)
if (v[i] == -1) v[i] = 0;
bool ok = 1;
for (i = 1; i <= n && ok; i++) {
bool now = 0;
if (input[(i-1)*2].fi == 0) now |= v[input[(i-1)*2].se];
else now |= v[oth(m, input[(i-1)*2].se)];
if (input[(i-1)*2+1].fi == 0) now |= v[input[(i-1)*2+1].se];
else now |= v[oth(m, input[(i-1)*2+1].se)];
ok &= now;
}
if (!ok) fout << -1;
else for (i = 1; i <= m; i++) fout << v[i] << ' ';
fin.close(); fout.close();
return 0;
}
/**
3 4
+ 1 + 2
- 1 + 3
+ 4 - 2
3 3
+ 1 + 2
- 1 + 3
- 3 - 2
**/