题意有点模糊,其实是这样的:对于每一个队伍,队长和其余两人(视为整体)至少留下一个,且不能同时留下;对于每一对队员,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 "); 103 } 104 else 105 { 106 printf("no "); 107 } 108 } 109 return 0; 110 }