HDU-3062-Party(2-SAT)

152 篇文章 0 订阅
10 篇文章 0 订阅

中文题。

思路:

两种: 一种是kuangbin的两层dfs写法(我竟然wa了之后怀疑bin神板子。。T_T,最后发现自己智障点写错了)。没毛病,可以套。。

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<math.h>
using namespace std;
const int maxn=1000005;
struct node
{
    int v,next;
} edge[maxn],edgef[maxn];
int head[maxn];
int headf[maxn];
int tot1,tot2;
int vis1[maxn],vis2[maxn];
int belong[maxn];
int T[maxn];
int Bcnt,Tcnt;
void add(int u,int v)
{
    edge[++tot1].v=v;
    edge[tot1].next=head[u];
    head[u]=tot1;

    edgef[++tot2].v=u;
    edgef[tot2].next=headf[v];
    headf[v]=tot2;
}

void init()
{
    memset(head,-1,sizeof(head));
    memset(headf,-1,sizeof(headf));
    memset(vis1,0,sizeof(vis1));
    memset(vis2,0,sizeof(vis2));
    tot1=tot2=0;
    Bcnt=Tcnt=0;
}

void dfs1(int u) //正向图 dfs ,算结束时间
{
    vis1[u]=1;
    for(int i=head[u]; i!=-1; i=edge[i].next)
    {
        int v=edge[i].v;
        if(!vis1[v])
            dfs1(v);
    }
    T[++Tcnt]=u;
}

void dfs2(int u)
{
    vis2[u]=1;
    belong[u]=Bcnt;
    for(int i=headf[u]; i!=-1; i=edgef[i].next)
    {
        int v=edgef[i].v;
        if(!vis2[v])
            dfs2(v);
    }
}
int judge(int n)
{
    for(int i=0; i<2*n; i++)
    {
        if(!vis1[i])
            dfs1(i);
    }
    for(int i=Tcnt; i>=1; i--)
    {
        if(!vis2[T[i]])
        {
            Bcnt++;
            dfs2(T[i]);
        }
    }
    for(int i=0; i<=2*n-2; i+=2)
    {
        if(belong[i]==belong[i+1])
            return 0;
    }
    return 1;
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        for(int i=0; i<m; i++)
        {
            int a,b,c,d;
            scanf("%d%d%d%d",&a,&b,&c,&d);
            int u=2*a+c,v=2*b+d;
            add(u,v^1);
            add(v,u^1);
        }
        if(judge(n))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}


  第二种是正常的tarjan求强连通


//#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1000005;
struct Edge
{
    int to,next;
} edge[maxn];
int head[maxn],tot;
int Low[maxn],DFN[maxn],Stack[maxn],Belong[maxn];
int Index,top;
int scc;
const int inf=0x3f3f3f3f;
bool Instack[maxn];
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 != -1; 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];
            Belong[v] = scc;
            Instack[v] = false;
        }
        while( v!= u );
    }
}


int main()
{
    int n,m;
    while(scanf("%d",&n)!=EOF)
    {
        int a,b,c,d;
        memset(DFN,0,sizeof(DFN));
        memset(Instack,false,sizeof(Instack));
        Index = scc = top = tot=0;
        memset(edge,0,sizeof(edge));
        memset(head,-1,sizeof(head));
        scanf("%d",&m);
        for(int i=0; i<m; ++i)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            a=(a<<1)+c;
            b=(b<<1)+d;
            addedge(a,b^1);
            addedge(b,a^1);
        }
        for(int i=0; i<n<<1; ++i)
            if(!DFN[i])
                Tarjan(i);
        int flag=0;
        for(int i=0; i<n; ++i)
        {
            if(Belong[i<<1]==Belong[(i<<1)^1])
                flag=1;
        }
        if(flag)printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值