zoukankan      html  css  js  c++  java
  • hdu 3062 Party 2-SAT

    题目链接:HDU - 3062

    有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席。在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时出现在聚会上的。有没有可能会有n 个人同时列席?
    Input
    n: 表示有n对夫妻被邀请 (n<= 1000)
    m: 表示有m 对矛盾关系 ( m < (n - 1) * (n -1))
    在接下来的m行中,每行会有4个数字,分别是 A1,A2,C1,C2
    A1,A2分别表示是夫妻的编号
    C1,C2 表示是妻子还是丈夫 ,0表示妻子 ,1是丈夫
    夫妻编号从 0 到 n -1
    Output
    如果存在一种情况 则输出YES
    否则输出 NO 
    题目描述:中文题目,如上所述。
    算法分析:2-SAT的入门题,如果u和v有矛盾,选u的同时必须选v^1,选v的同时只能选择u^1,然后缩点判断即可。
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cmath>
      6 #include<algorithm>
      7 #include<queue>
      8 #include<vector>
      9 #include<stack>
     10 using namespace std;
     11 const int maxn=2000+10;
     12 const int M=1000000+10;
     13 
     14 int n,m;
     15 struct node
     16 {
     17     int v,next;
     18 }edge[M*4];
     19 int head[maxn],edgenum;
     20 int dfn[maxn],low[maxn],scc[maxn],ind[maxn],vis[maxn];
     21 stack<int> S;
     22 int color[maxn],f[maxn];
     23 int dfs_clock,scc_cnt;
     24 vector<int> dag[maxn];
     25 void add(int u,int v)
     26 {
     27     edge[edgenum].v=v ;edge[edgenum].next=head[u] ;
     28     head[u]=edgenum++;
     29 }
     30 void init()
     31 {
     32     memset(head,-1,sizeof(head));
     33     memset(vis,0,sizeof(vis));
     34     memset(dfn,0,sizeof(dfn));
     35     memset(ind,0,sizeof(ind));
     36     memset(color,0,sizeof(color));
     37     edgenum=dfs_clock=scc_cnt=0;
     38 }
     39 void tarjan(int u)
     40 {
     41     dfn[u]=low[u]= ++dfs_clock;
     42     vis[u]=1;
     43     S.push(u);
     44     for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     45     {
     46         int v=edge[i].v;
     47         if (!dfn[v])
     48         {
     49             tarjan(v);
     50             low[u]=min(low[u],low[v]);
     51         }
     52         else if (vis[v])
     53             low[u]=min(low[u],dfn[v]);
     54     }
     55     if (low[u]==dfn[u])
     56     {
     57         scc_cnt++;
     58         while (true)
     59         {
     60             int v=S.top() ;S.pop() ;
     61             vis[v]=0;
     62             scc[v]=scc_cnt;
     63             if (u==v) break;
     64         }
     65     }
     66 }
     67 void buildDag(int n)
     68 {
     69     for (int u=0 ;u<2*n ;u++)
     70     {
     71         for (int i=head[u] ;i!=-1 ;i=edge[i].next)
     72         {
     73             int v=edge[i].v;
     74             if (scc[v] != scc[u])
     75             {
     76                 dag[scc[v]].push_back(scc[u]);
     77                 ind[scc[u]]++;
     78             }
     79         }
     80     }
     81 }
     82 void topsort()
     83 {
     84     queue<int> Q;
     85     for (int i=1 ;i<=scc_cnt ;i++) if (!ind[i]) Q.push(i);
     86     while (!Q.empty())
     87     {
     88         int u=Q.front() ;Q.pop();
     89         if (!color[u]) color[u]=1,color[f[u]]=2;
     90         for (int i=0 ;i<(int)dag[u].size() ;i++)
     91         {
     92             int v=dag[u][i];
     93             ind[v]--;
     94             if (!ind[v]) Q.push(v);
     95         }
     96     }
     97 }
     98 void solve(int n)
     99 {
    100     int flag=0;
    101     for (int i=0 ;i<2*n ;i++) if (!dfn[i]) tarjan(i);
    102     for (int i=0 ;i<n ;i++)
    103     {
    104         if(scc[2*i]==scc[(2*i)^1])
    105         {
    106             printf("NO
    ");
    107             flag=1;
    108             return ;
    109         }
    110         //else f[scc[i]]=scc[i+1],f[scc[i+1]]=scc[i];
    111     }
    112     if (!flag) printf("YES
    ");
    113 //    for (int i=0 ;i<=scc_cnt ;i++) dag[i].clear();
    114 //    buildDag(n);
    115 //    topsort();
    116     return ;
    117 }
    118 int main()
    119 {
    120     while (scanf("%d%d",&n,&m)!=EOF)
    121     {
    122         init();
    123         int a,b,c,d;
    124         for (int i=0 ;i<m ;i++)
    125         {
    126             scanf("%d%d%d%d",&a,&b,&c,&d);
    127             int u=2*a+c,v=2*b+d;
    128             add(u,v^1) ;add(v,u^1);
    129         }
    130         solve(n);
    131     }
    132     return 0;
    133 }
  • 相关阅读:
    单链表的实现C语言版
    顺序表的基本方法实现C语言版
    算法
    Redis
    Linux安装python3.6.1
    Markdown 基本使用手册
    设计Django个人博客网站
    RabbitMQ消息队列
    堡垒机 Paramiko 模块
    进程、线程、协程总结
  • 原文地址:https://www.cnblogs.com/huangxf/p/4427812.html
Copyright © 2011-2022 走看看