2-sat模板- 输出可行解

来源:互联网 发布:淘宝怎么添加收藏链接 编辑:程序博客网 时间:2024/06/07 04:58

自己写的代码

using namespace std;const int maxn = 1e6;int head[maxn];int DFN[maxn],LOW[maxn],stk[maxn],visit[maxn],belong[maxn];vector<int> scc[maxn];int tot,idx,cnt,sccnum;int n,color[maxn],degree[maxn],pos[maxn];struct Es{     int v;     int next;     int cost; }Es[maxn<<1];  vector<int> bkG[maxn];void init(){     sccnum = tot = idx = cnt = 0;     memset(head,-1,sizeof(head));     memset(DFN,0,sizeof(DFN));     memset(LOW,0,sizeof(LOW));     memset(visit,0,sizeof(visit)); memset(color,0,sizeof(color)); memset(degree,0,sizeof(degree));memset(pos,0,sizeof(pos));    for(int i = 0;i < maxn;i++) scc[i].clear();    for(int i = 0;i < maxn;++i) bkG[i].clear();}inline void add_edge(int i,int j,int cost = 1){       Es[cnt].v = j;     Es[cnt].cost = cost;     Es[cnt].next = head[i];     head[i] = cnt++; }   void tarjan(int x){     DFN[x]=LOW[x]=++tot;     stk[++idx]=x;     visit[x]=1;     for(int i=head[x];i!=-1;i=Es[i].next)     {         if(!DFN[Es[i].v]) {             tarjan(Es[i].v);             LOW[x] = min(LOW[x],LOW[Es[i].v]);         }         else if(visit[Es[i].v ]){               LOW[x] = min(LOW[x],DFN[Es[i].v]);         }     }     if(LOW[x]==DFN[x])     {      ++sccnum;         do{             int item = stk[idx];             belong[item] = sccnum;             scc[sccnum].push_back(item);             visit[item]=0;             idx--;         }while(x!=stk[idx+1]);     }     return ;}bool check(){for(int i = 1;i <= n;i++){if(belong[i] == belong[i+n]) return false;}return true;}bool solve(){for(int i = 1;i <= 2*n;++i )if(!DFN[i]) tarjan(i);if(!check()) return false;for(int i = 1;i <= n;++i){if(!pos[belong[i]]){pos[belong[i]] = belong[i+n];pos[belong[i+n]] = belong[i];}}for(int i = 1;i <= 2*n;++i){for(int e = head[i];e != -1;e = Es[e].next){int v = Es[e].v;if(belong[i] != belong[v]){degree[belong[i]]++;bkG[belong[v]].push_back(belong[i]);}}}queue<int> que;for(int i = 1;i <= sccnum;++i){if(!degree[i])que.push(i);}while(!que.empty()){int u = que.front();que.pop();if(!color[u]){color[u] = 1;color[pos[u]] = 2;}for(int i = 0;i < bkG[u].size();++i){int v = bkG[u][i];degree[v]--;if(!degree[v])que.push(v);}}//在这里准备输出答案//为1表示选中,为2表示为选中/*for(int i = 1;i <= n;++i){if(color[belong[i]] == 1) {//Yes}else{//No}} */return true;}

//使用方法

1.init()

2.用add_edge建图

3.用solve()函数求解



阅读全文
1 0
原创粉丝点击