【POJ 3062】Party(2-SAT、tarjan)

2-SAT的入门题。

a,a‘,b,b‘分别表示两对夫妇,如果a,b有矛盾,那么a要来,就只能来b‘,b要来,就只能来a‘。于是建了两条边(a,b‘),(b,a‘)。

用tarjan强连通分量缩点染色后,如果同一对夫妇染色相同,说明两个要么都来,要么都不来,就不可能有解了。否则,形成的强连通分量中必定是对称的(abc是强连通分量,那么a‘b‘c‘也会在一个强连通分量里),于是只要选择几个强连通分量就可以每个集合都选1个。

#include <cstdio>
#include <cstring>
const int N=2001;
const int M=4000010;
struct Edge
{
    int to,next;
}edge[M];
int head[N],tot;
int Low[N],DFN[N],Stack[N],Belong[N];
int Index,top;
int scc;
bool Instack[N];
void addedge(int u,int v)
{
    edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}
void Tarjan(int u)
{
    int v;
    Low[u] = DFN[u] = ++Index;
    Stack[top++] = u;
    Instack[u] = true;
    for(int i = head[u];~i;i = edge[i].next)
    {
        v = edge[i].to;
        if( !DFN[v] )
        {
            Tarjan(v);
            if(Low[u] > Low[v])Low[u] = Low[v];
        }
        else if(Instack[v] && Low[u] > DFN[v])
            Low[u] = DFN[v];
    }
    if(Low[u] == DFN[u])
    {
                scc++;
                do
                {
                        v = Stack[--top];
                        Instack[v] = false;
                        Belong[v] = scc;
                }
                while( v != u);
    }
}
void solve(int n)
{
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof Instack);
        Index = scc = top = 0;
        for(int i = 0;i < n*2;i++)
                if(!DFN[i])
                        Tarjan(i);
        int ok=1;
        for(int i=0;i<n&&ok;i++)
            if(Belong[i*2]==Belong[i*2+1])
                ok=0;
        if(ok)
            puts("YES");
        else
            puts("NO");
}
void init()
{
        tot = 0;
        memset(head,-1,sizeof head);
}
int main()
{
    int n,m;
    int a1,a2,c1,c2;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        while(m--)
        {
            scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
            addedge(a1*2+c1,a2*2+1-c2);
            addedge(a2*2+c2,a1*2+1-c1);
        }
        solve(n);
    }
    return 0;
}

  

时间: 2024-10-11 00:12:20

【POJ 3062】Party(2-SAT、tarjan)的相关文章

【poj 1961】Period(字符串--KMP循环节)

题意:给你一个字符串,求这个字符串到第 i 个字符为止的重复子串的个数. 解法:判断重复子串的语句很重要!!if (p && i%(i-p)==0) printf("%d %d\n",i,i/(i-p)); 我之前一直不是很理解,而实际上多枚举几种情况就好了.若是重复的,那么next[i]肯定是最大值,值余下一个循环节不同:而若不是,next[i]表示的前缀和后缀串的和重叠部分不一样以外的部分就肯定空出来,不能整除的.(P.S.我在说些什么......m(._.)m)

【POJ 1201】 Intervals(差分约束系统)

[POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23817   Accepted: 9023 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p

【POJ 3071】 Football(DP)

[POJ 3071] Football(DP) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4350   Accepted: 2222 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all tea

【POJ 3034】 Whac-a-Mole(DP)

[POJ 3034] Whac-a-Mole(DP) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3621   Accepted: 1070 Description While visiting a traveling fun fair you suddenly have an urge to break the high score in the Whac-a-Mole game. The goal of the W

【POJ 1151】 Atlantis(离散化+扫描线)

[POJ 1151] Atlantis(离散化+扫描线) Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20223   Accepted: 7634 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even inclu

【POJ 3070】Fibonacci(矩阵快速幂)

[POJ 3070]Fibonacci(矩阵快速幂) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12333   Accepted: 8752 Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn ? 1 + Fn ? 2 for n ≥ 2. For example, the first ten terms of the

【HDU 5721】Palace(平面最近点对)

[HDU 5721]Palace(平面最近点对) Palace Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 404    Accepted Submission(s): 104 Problem Description The last trial Venus imposes on Psyche is a quest to the

【UOJ#50】【UR #3】链式反应(分治FFT,动态规划)

[UOJ#50][UR #3]链式反应(分治FFT,动态规划) 题面 UOJ 题解 首先把题目意思捋一捋,大概就是有\(n\)个节点的一棵树,父亲的编号大于儿子. 满足一个点的儿子有\(2+c\)个,其中\(c\in A\),且\(c\)个儿子是叶子,另外\(2\)个存在子树,且两种点的链接的边是不同的,求方案数. 那么就考虑一个暴力\(dp\),设\(f[i]\)表示有\(i\)个节点的树的个数. 那么枚举它两个有子树的子树大小,然后把编号给取出来,得到: \[f[i]=\frac{1}{2}

【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)

2288: [POJ Challenge]生日礼物 Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知道选择元素之和的最大值.你能帮助她吗? Input 第1行,两个整数 N (1 ≤ N ≤ 105) 和 M (0 ≤ M ≤ 105), 序列的长度和可以选择的部分. 第2行, N 个整数 A1, A2, ..., AN (0