zoukankan      html  css  js  c++  java
  • HDU3062(2-SAT+模型1+暴力+scc)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3062

    题目意思:有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席。在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时出现在聚会上的。n 个人同时列席是否有解。

    题目思路:暴力法走一遍,如果solve成功则可以;也可以tarjan缩点,用定理。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N = 2005;
     4 const int M = N*N;
     5 struct Edge{
     6     int v,next;
     7 }edge[M];
     8 int head[N],sta[N],cnt,top;
     9 bool vis[N];
    10 void init()
    11 {
    12     memset(head,-1,sizeof(head));
    13     memset(vis,false,sizeof(vis));
    14     memset(sta,0,sizeof(sta));
    15     cnt = top = 0;
    16 }
    17 void inline add(int u,int v)
    18 {
    19     edge[++cnt].v = v;
    20     edge[cnt].next = head[u];
    21     head[u] = cnt; 
    22 }
    23 bool dfs(int u)
    24 {
    25     if(vis[u^1]) return false;
    26     if(vis[u]) return true;
    27     vis[u] = true;
    28     sta[top++] = u;
    29     for(int i = head[u];i != -1;i = edge[i].next)
    30     {
    31         if(!dfs(edge[i].v)) return false;
    32     }
    33     return true;
    34 }
    35 bool solve(int n)
    36 {
    37     for(int i = 0;i < (n<<1);i += 2)
    38     {
    39         if(!vis[i]&&!vis[i^1])
    40         {
    41             top = 0;
    42             if(!dfs(i))
    43             {
    44                 while(top) vis[sta[--top]] = false;
    45                 if(!dfs(i^1)) return false;
    46             }
    47         }
    48     }
    49     return true;
    50 }
    51 int main()
    52 {
    53     int n,m;
    54     while(~scanf("%d%d",&n,&m))
    55     {
    56         init();
    57         for(int i = 1;i <= m; i++)
    58         {
    59             int a1,a2,c1,c2;
    60             scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
    61             if(c1 == 0) a1 = (a1<<1);
    62             else a1 = (a1<<1) + 1;
    63             if(c2 == 0) a2 = (a2<<1);
    64             else a2 = (a2<<1) + 1;
    65             add(a1^1,a2);
    66             add(a2^1,a1);
    67         }
    68         if(solve(n)) printf("YES
    ");
    69         else printf("NO
    ");
    70     }
    71     return 0;
    72 } 
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using std::min;
     5 const int N = 2010, M = N * N;
     6 struct Edge
     7 {
     8     int to, nex;
     9 } edge[M];
    10 int num_e;
    11 int head[N];
    12 int dfn[N], low[N], scc[N], sz[N], idx, tot;
    13 bool insta[N];
    14 int sta[N], top;
    15 void init() {
    16     num_e = 0, top = 0, idx = 0, tot = 0;
    17     memset(head, 0, sizeof(head));
    18     memset(insta, 0, sizeof(insta));
    19     memset(scc, 0, sizeof(scc));
    20     memset(dfn, 0, sizeof(dfn));
    21 }
    22 void add_edge(int x, int y) {
    23     edge[++num_e].to = y;
    24     edge[num_e].nex = head[x];
    25     head[x] = num_e;
    26 }
    27 void tarjan(int u) {
    28     dfn[u] = low[u] = ++idx;
    29     sta[++top] = u;
    30     insta[u] = true;
    31     for (int i = head[u]; i; i = edge[i].nex) {
    32         int v = edge[i].to;
    33         if (!dfn[v]) {
    34             tarjan(v);
    35             low[u] = min(low[u], low[v]);
    36         }
    37         else if (insta[v]) low[u] = min(low[u], dfn[v]);
    38     }
    39     if (dfn[u] == low[u]) {
    40         ++tot;
    41         do {
    42             scc[sta[top]] = tot;
    43             sz[tot]++;
    44             insta[sta[top]] = false;
    45         } while (sta[top--] != u);
    46     }
    47 }
    48 
    49 int main() {
    50     int n, m;
    51     while (~scanf("%d %d", &n, &m)) {
    52         init();
    53         for (int i = 0, a1, a2, c1, c2; i < m; i++) {
    54             scanf("%d %d %d %d", &a1, &a2, &c1, &c2);
    55             add_edge(2 * a1 + c1, 2 * a2 + 1 - c2);
    56             add_edge(2 * a2 + c2, 2 * a1 + 1 - c1);
    57         }
    58         for (int i = 0; i < 2 * n; i++) {
    59             if (!dfn[i]) tarjan(i);
    60         }
    61         bool ans = true;
    62         for (int i = 0; i < 2 * n; i += 2) {
    63             if (scc[i] == scc[i+1]) {
    64                 ans = false;
    65                 break;
    66             }
    67         }
    68         printf("%s
    ", ans ? "YES" : "NO");
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    前端页面有哪三层构成,分别是什么?作用是什么?
    如何使用jQuery设置背景的透明度
    笔试基础
    我的设计模式3
    C++ 输入输出流
    我的设计模式2
    剑指offer: 38 数字在排序数组中出现的次数
    我的设计模式
    常用算法设计与分析
    iOS viewController 和 view 的创建消失生命周期总结
  • 原文地址:https://www.cnblogs.com/Mingusu/p/12533273.html
Copyright © 2011-2022 走看看