hdu 3062 Party 最裸2-sat题目

http://acm.hdu.edu.cn/showproblem.php?pid=3062

题意:中文...

思路:

来自伍昱的《由对称性解2-SAT问题

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

把确定不矛盾的双方建立边,然后tarjan缩点。判断每一对夫妻是否属于不同的环,如果存在同一环里,则无解,否则有解

//#pragma comment(linker,"/STACK:327680000,327680000")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>

#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define ll long long
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)int
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("din.txt", "r", stdin)
#define Write() freopen("dout.txt", "w", stdout);

#define N 2005

using namespace std;


int dfn[N],low[N];
int belong[N],stk[N];
bool ins[N];
int cnt,idx,top;
vector<int>iVc[N];

int n,m;

void tarjan(int u)
{
    int j;
    dfn[u] = low[u] = ++idx;
    stk[++top] = u;
    ins[u] = true;
    int sz = iVc[u].size();
    for (j = 0; j < sz; ++j)
    {
        int v = iVc[u][j];
        if (dfn[v] == -1)
        {
            tarjan(v);
            low[u] = min(low[u],low[v]);
        }
        else if (ins[v])
        {
            low[u] = min(low[u],dfn[v]);
        }
    }
    if (dfn[u] == low[u])
    {
        cnt++;
        do
        {
            j = stk[top--];
            ins[j] = false;
            belong[j] = cnt;
        }while (j != u);
    }
}
void solve()
{
    int i;
    //tarjan缩点
    for (i = 0; i < 2*n; ++i)
    {
        if (dfn[i] == -1)
        {
            tarjan(i);
        }
    }
    //判断夫妻是否属于同一环
    bool flag = false;
    for (i = 0; i < n; ++i)
    {
        if (belong[2*i] == belong[2*i + 1])
        {
            flag = true;
            break;
        }
    }
    if (!flag)
    printf("YES\n");
    else
    printf("NO\n");
}
void init()
{
    int i;
    for (i = 0; i <= 2*n; ++i)
    {
        iVc[i].clear();
        dfn[i] = low[i] = -1;
        ins[i] = false;
    }
    top = idx = cnt = 0;
}
int main()
{
    int i;
    int a1,a2,b1,b2;
    while (~scanf("%d%d",&n,&m))
    {
        init();
        for (i = 0; i < m; ++i)
        {
            //不矛盾的建边
            scanf("%d%d%d%d",&a1,&a2,&b1,&b2);
            iVc[a1*2 + b1].push_back(a2*2 + 1 - b2);
            iVc[a2*2 + b2].push_back(a1*2 + 1 - b1);
        }
        solve();
    }
    return 0;
}

  

 

 

posted @ 2013-01-26 11:14  E_star  阅读(265)  评论(0编辑  收藏  举报