首页 > 代码库 > 2-sat

2-sat

今天才会2-sat,是不是没有救了...

Anna最近在学sat2...真是心有灵犀啊...

 

参考链接:

    http://wenku.baidu.com/view/afd6c436a32d7375a41780f2.html

 

基本方法:

    1.构图
    2.求图的极大强连通子图
    3.把每个子图收缩成单个节点,根据原图关系构造一个有向无环图
    4.判断是否有解,无解则输出(退出)
    5.对新图进行拓扑排序
    6.自底向上进行选择、删除
    7.输出

 

hdu 3062 party

 入门题...

 1 #include <stack> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7  8 const int maxn = 2000 + 2; 9 const int maxm = 4000000 + 2;10 11 stack<int> s;12 bool in[maxn];13 vector<int> G[maxn];14 int n, m, scc, Index, dfn[maxn], low[maxn], belong[maxn];15 16 void tarjan(int now){17     dfn[now] = low[now] = ++ Index;18     in[now] = true, s.push(now);19 20     for (int i = 0, len = G[now].size(), to; i < len; i ++){21         to = G[now][i];22         if (!dfn[to]){23             tarjan(to);24             low[now] = min(low[now], low[to]);25         }26 27         else if (in[to])28             low[now] = min(low[now], dfn[to]);29     }30 31     if (low[now] == dfn[now]){32         ++ scc;    33 34         int u;35         do {36             u = s.top();37             s.pop(), in[u] = false;38             belong[u] = scc;39         } while (u ^ now);40     }41 }42 43 inline void init(){44     memset(low, 0, sizeof low);45     memset(dfn, 0, sizeof dfn);46     memset(in, false, sizeof in);47     Index = scc = 0;48     while (not s.empty())49         s.pop();50     for (int i = 0; i < 2 * n; i ++)51         G[i].clear();52 53     for (int i = 0, a, b, x, y, g1, g2; i < m; i ++){54         scanf("%d %d %d %d", &a, &b, &g1, &g2);55 56         x = a * 2 + 1 - g1, y = b * 2 + 1 - g2;57         a = a * 2 + g1, b = b * 2 + g2;58 59         G[a].push_back(y), G[b].push_back(x);60     }61 }62 63 inline bool two_sat(){64     init();65     for (int i = 0; i < n * 2; i ++)66         if (!dfn[i])67             tarjan(i);68 69     for (int i = 0; i < n; i ++)70         if (belong[i * 2] == belong[i * 2 + 1])71             return false;72 73     return true;74 }75 76 int main(){77     while (scanf("%d %d", &n, &m) == 2)78         puts(two_sat() ? "YES" : "NO");79 }
hdu 3062

 

2-sat