hdu 1824 2-sat

题意有点模糊,其实是这样的:对于每一个队伍,队长和其余两人(视为整体)至少留下一个,且不能同时留下;对于每一对队员,A留下则B不能留下,B留下则A不能留下。建图求解即可,不过还是想吐槽一下出题人的中文,o(╯□╰)o,请叫我建边小王子。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 using namespace std;
  6 
  7 const int N = 3000;
  8 const int M = 30000;
  9 int head[N * 2];
 10 int s[N * 2];
 11 bool mark[N * 2];
 12 int n, t, m, e, c;
 13 
 14 struct Edge
 15 {
 16     int v, next;
 17 } edge[M];
 18 
 19 void addEdge( int u, int v )
 20 {
 21     edge[e].v = v;
 22     edge[e].next = head[u];
 23     head[u] = e++;
 24 }
 25 
 26 void init()
 27 {
 28     e = 0;
 29     memset( head, -1, sizeof(head) );
 30     memset( mark, false, sizeof(mark) );
 31 }
 32 
 33 bool dfs( int u )
 34 {
 35     if ( mark[u ^ 1] ) return false;
 36     if ( mark[u] ) return true;
 37     mark[u] = true;
 38     s[c++] = u;
 39     for ( int i = head[u]; i != -1; i = edge[i].next )
 40     {
 41         int v = edge[i].v;
 42         if ( !dfs(v) ) return false;
 43     }
 44     return true;
 45 }
 46 
 47 bool solve()
 48 {
 49     for ( int i = 0; i < 2 * n; i += 2 )
 50     {
 51         if ( !mark[i] && !mark[i + 1] )
 52         {
 53             c = 0;
 54             if ( !dfs(i) )
 55             {
 56                 while ( c )
 57                 {
 58                     c--;
 59                     mark[s[c]] = false;
 60                 }
 61                 if ( !dfs( i + 1 ) ) return false;
 62             }
 63         }
 64     }
 65     return true;
 66 }
 67 
 68 int main ()
 69 {
 70     while ( scanf("%d%d", &t, &m) != EOF )
 71     {
 72         n = 3 * t;
 73         init();
 74         while ( t-- )
 75         {
 76             int x, y, z;
 77             scanf("%d%d%d", &x, &y, &z);
 78             x = x * 2, y = y * 2, z = z * 2;
 79             addEdge( x, y ^ 1 );
 80             addEdge( x, z ^ 1 );
 81             addEdge( x ^ 1, y );
 82             addEdge( x ^ 1, z );
 83             addEdge( y, z );
 84             addEdge( y, x ^ 1 );
 85             addEdge( y ^ 1, x );
 86             addEdge( y ^ 1, z ^ 1 );
 87             addEdge( z, x ^ 1 );
 88             addEdge( z, y );
 89             addEdge( z ^ 1, x );
 90             addEdge( z ^ 1, y ^ 1 );
 91         }
 92         while ( m-- )
 93         {
 94             int x, y;
 95             scanf("%d%d", &x, &y);
 96             x = x * 2, y = y * 2;
 97             addEdge( x ^ 1, y );
 98             addEdge( y ^ 1, x );
 99         }
100         if ( solve() )
101         {
102             printf("yes\n");
103         }
104         else
105         {
106             printf("no\n");
107         }
108     }
109     return 0;
110 }

 

posted @ 2015-08-03 16:27  hxy_has_been_used  阅读(172)  评论(0编辑  收藏  举报