洛谷题单指南-连通性问题-P4782 【模板】2-SAT
原题链接:https://www.luogu.com.cn/problem/P4782
题意解读:2-SAT模版题。
解题思路:
100分代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2000005, M = 2000005;
int head[N], to[M], nxt[M], idx;
int dfn[N], low[N], timestamp;
stack<int> stk;
bool vis[N];
int scc[N], cnt;
bool ans[N];
int n, m;
void add(int a, int b)
{
to[++idx] = b;
nxt[idx] = head[a];
head[a] = idx;
}
void tarjan(int u)
{
dfn[u] = low[u] = ++timestamp;
stk.push(u);
vis[u] = true;
for(int i = head[u]; i; i = nxt[i])
{
int v = to[i];
if(!dfn[v])
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if(vis[v])
{
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u])
{
cnt++;
while(true)
{
int t = stk.top(); stk.pop();
scc[t] = cnt;
vis[t] = false;
if(t == u) break;
}
}
}
bool check()
{
for(int i = 1; i <= n * 2; i++) //注意节点总数是2n
if(!dfn[i])
tarjan(i);
for(int i = 1; i <= n; i++)
if(scc[i] == scc[i + n]) //i和非i在同一个强联通分量
return false;
return true;
}
int main()
{
cin.tie(0), cout.tie(0), ios::sync_with_stdio(false);
cin >> n >> m;
for(int i = 1;i <= m; i++)
{
int x, a, y, b;
cin >> x >> a >> y >> b;
if(a == 1 && b == 1) // x || y
{
add(x + n, y); // !x -> y
add(y + n, x); // !y -> x
}
else if(a == 1 && b == 0) // x || !y
{
add(x + n, y + n); // !x -> !y
add(y, x); // y -> x
}
else if(a == 0 && b == 1) // !x || y
{
add(x, y); // x -> y
add(y + n, x + n); // !y -> !x
}
else // !x || !y
{
add(x, y + n); // x -> !y
add(y, x + n); // y -> !x
}
}
if(!check()) cout << "IMPOSSIBLE" << endl;
else
{
cout << "POSSIBLE" << endl;
for(int i = 1; i <= n; i++)
cout << (scc[i] < scc[i + n]) << " "; //i比非i的拓扑序靠前则是1,否则是0
}
return 0;
}
浙公网安备 33010602011771号