首页 > 代码库 > [HDU3062]Party

[HDU3062]Party

传送门

2-sat问题,只需要判断yes或no

所以可以直接连边,缩点,判断同一组的是否在同一个块中。

技术分享
 1 #include <cstdio>
 2 #include <stack>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define N 1000001
 7 
 8 int n, m, cnt, idx, sz;
 9 int head[N], to[N << 1], next[N << 1], dfn[N], low[N], belong[N];
10 bool ins[N], flag;
11 std::stack <int> s;
12 
13 inline void add(int x, int y)
14 {
15     to[cnt] = y;
16     next[cnt] = head[x];
17     head[x] = cnt++;
18 }
19 
20 inline void tarjan(int u)
21 {
22     int i, v;
23     dfn[u] = low[u] = ++idx;
24     ins[u] = 1;
25     s.push(u);
26     for(i = head[u]; i != -1; i = next[i])
27     {
28         v = to[i];
29         if(!dfn[v])
30         {
31             tarjan(v);
32             low[u] = std::min(low[u], low[v]);
33         }
34         else if(ins[v]) low[u] = std::min(low[u], dfn[v]);
35     }
36     if(low[u] == dfn[u])
37     {
38         ++sz;
39         do
40         {
41             v = s.top();
42             s.pop();
43             ins[v] = 0;
44             belong[v] = sz;
45         }while(u != v);
46     }
47 }
48 
49 int main()
50 {
51     int i, j, a, b, c, d;
52     while(~scanf("%d", &n))
53     {
54         memset(head, -1, sizeof(head));
55         memset(ins, 0, sizeof(ins));
56         memset(dfn, 0, sizeof(dfn));
57         idx = cnt = sz = 0;
58         while(!s.empty()) s.pop();
59         scanf("%d", &m);
60         for(i = 1; i <= m; i++)
61         {
62             scanf("%d %d %d %d", &a, &b, &c, &d);
63             a = (a << 1) + c;
64             b = (b << 1) + d;
65             add(a, b ^ 1);
66             add(b, a ^ 1);
67         }
68         for(i = 0; i < n << 1; i++)
69          if(!dfn[i])
70           tarjan(i);
71         flag = 0;
72         for(i = 0; i < n; i++)
73          if(belong[i << 1] == belong[(i << 1) ^ 1])
74           flag = 1;
75         if(flag) printf("NO\n");
76         else printf("YES\n");
77     }
78     return 0;
79 }
View Code

 

[HDU3062]Party