zoukankan      html  css  js  c++  java
  • HDU3062(2-SAT)

    Party

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6682    Accepted Submission(s): 2194


    Problem Description

    有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 
     

     

    Sample Input

    2 1 0 1 1 1
     

    Sample Output

    YES
     

    Source

     
    令夫为a,妻为a非
    有矛盾的夫妻之间连边,不能出现在同一个强连通分量中。
      1 //2017-08-26
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 #include <vector>
      7 
      8 using namespace std;
      9 
     10 const int N = 5010;
     11 const int M = N*N;
     12 int head[N], rhead[N], tot, rtot;
     13 struct Edge{
     14     int to, next;
     15 }edge[M], redge[M];
     16 
     17 void init(){
     18     tot = 0;
     19     rtot = 0;
     20     memset(head, -1, sizeof(head));
     21     memset(rhead, -1, sizeof(rhead));
     22 }
     23 
     24 void add_edge(int u, int v){
     25     edge[tot].to = v;
     26     edge[tot].next = head[u];
     27     head[u] = tot++;
     28 
     29     redge[rtot].to = u;
     30     redge[rtot].next = rhead[v];
     31     rhead[v] = rtot++;
     32 }
     33 
     34 vector<int> vs;//后序遍历顺序的顶点列表
     35 bool vis[N];
     36 int cmp[N];//所属强连通分量的拓扑序
     37 
     38 //input: u 顶点
     39 //output: vs 后序遍历顺序的顶点列表
     40 void dfs(int u){
     41     vis[u] = true;
     42     for(int i = head[u]; i != -1; i = edge[i].next){
     43         int v = edge[i].to;
     44         if(!vis[v])
     45           dfs(v);
     46     }
     47     vs.push_back(u);
     48 }
     49 
     50 //input: u 顶点编号; k 拓扑序号
     51 //output: cmp[] 强连通分量拓扑序
     52 void rdfs(int u, int k){
     53     vis[u] = true;
     54     cmp[u] = k;
     55     for(int i = rhead[u]; i != -1; i = redge[i].next){
     56         int v = redge[i].to;
     57         if(!vis[v])
     58           rdfs(v, k);
     59     }
     60 }
     61 
     62 //Strongly Connected Component 强连通分量
     63 //input: n 顶点个数
     64 //output: k 强连通分量数;
     65 int scc(int n){
     66     memset(vis, 0, sizeof(vis));
     67     vs.clear();
     68     for(int u = 0; u < n; u++)
     69       if(!vis[u])
     70         dfs(u);
     71     int k = 0;
     72     memset(vis, 0, sizeof(vis));
     73     for(int i = vs.size()-1; i >= 0; i--)
     74       if(!vis[vs[i]])
     75         rdfs(vs[i], k++);
     76     return k;
     77 }
     78 
     79 void solve(int n){
     80     for(int i = 0; i < n; i++){
     81         if(cmp[i] == cmp[i+n]){//a和NOT a在同一个强连通分量中,布尔方程无解
     82             cout<<"NO"<<endl;
     83             return;
     84         }
     85     }
     86     cout<<"YES"<<endl;//布尔方程有解
     87     return;
     88 }
     89 
     90 int main()
     91 {
     92     std::ios::sync_with_stdio(false);
     93     //freopen("inputA.txt", "r", stdin);
     94     int n, m;
     95     while(cin>>n>>m){
     96         init();
     97         int u, v, a, b;
     98         for(int i = 0; i < m; i++){
     99             cin>>u>>v>>a>>b;
    100             if(a == 0 && b == 0){// u && v
    101                 add_edge(u+n, v);// NOT u -> v
    102                 add_edge(v+n, u);// NOT v -> u
    103             }else if(a == 0 && b == 1){// u && NOT v
    104                 add_edge(u+n, v+n);// NOT u -> NOT v
    105                 add_edge(v, u);// v -> u
    106             }else if(a == 1 && b == 0){// NOT u && v
    107                 add_edge(u, v);// u -> v
    108                 add_edge(v+n, u+n);// NOT v -> NOT u
    109             }else if(a == 1 && b == 1){// NOT u && NOT v
    110                 add_edge(u, v+n);// u -> NOT v
    111                 add_edge(v, u+n);// v -> NOT u
    112             }
    113         }
    114         scc(n<<1);
    115         solve(n);
    116     }
    117 
    118     return 0;
    119 }
  • 相关阅读:
    欢迎大家来到氨帝萝卜的博客园
    Java利用自定义注解、反射实现简单BaseDao
    spring boot 2.0.1.RELEASE版本之消息总线 ConfigClient配置自动刷新
    spring cloud eureka server之端口8889之谜
    关于spring cloud “Finchley.RC2”版本在spring cloud config中的ArrayIndexOutOfBoundsException
    关于中间件、J2EE的一些概念
    IP地址 子网掩码 默认网关 DNS(转)
    知识点大图
    Javascript是单线程的深入分析(转)
    SQL查询--选择运算(1)
  • 原文地址:https://www.cnblogs.com/Penn000/p/7436462.html
Copyright © 2011-2022 走看看