关于2sat的建图
查看原帖
关于2sat的建图
434015
Calanosay楼主2021/6/3 21:56
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+5;
const int maxm=maxn<<1;
int head[maxn],w[maxm],v[maxm],nex[maxm],cnt,dis[maxn],vis[maxn];
int dfn[maxn],mp[maxn],low[maxn];
int sccid,idx;
stack<int> s;
void add(int x,int y){
    v[++cnt]=y;
    nex[cnt]=head[x];
    head[x]=cnt;
}
int n,m;
void tarjan(int x){
    dfn[x]=low[x]=++idx;
    s.push(x),vis[x]=1;
    for(int i=head[x];i;i=nex[i]){
        int to=v[i];
        if(!dfn[to]) {
            tarjan(to);
            low[x]=min(low[x],low[to]);
        }
        else if(vis[to])    low[x]=min(low[x],dfn[to]);
    }
    if(dfn[x]==low[x]){
        ++sccid;
        while(s.top()!=x){
            mp[s.top()]=sccid;
            vis[s.top()]=0;
            s.pop();
        }
        mp[s.top()]=sccid;
        vis[s.top()]=0;
        s.pop();
    }
}
int main(){
    ios::sync_with_stdio(false);
        cin.tie(0);cout.tie(0);
    cin>>n>>m;
    while(m--){
        int i,a,j,b;
        cin>>i>>a>>j>>b;
        i=(i<<1)+a;
        j=(j<<1)+b;
        add(i,j^1);add(j,i^1);
    }
    for(int i=1;i<=n*2;i++)   if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;i++)   if(mp[i<<1]==mp[i<<1|1]) {cout<<"IMPOSSIBLE";return 0;}
    for(int i=1;i<=n;i++)   cout<<(mp[i<<1]<mp[i<<1|1])<<' ';

}

这是我类似网络流的建法,也就是选和不选就差一个^1,因为我感觉+n的建法太麻烦了,难道不能这么建吗,还是说哪里出了什么问题

2021/6/3 21:56
加载中...