思路:很显然,让某一个孩子happy是一定可以做到的,但是同时有可能会让别的孩子unhappy,所以每一对这样的两个孩子之间存在”冲突”,如果在存在“冲突”的孩子之间建边的话,我们的问题就转化成了求二分图的最大独立集。具体为什么是二分图,博主也没有想明白...
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int N = 501; 7 const int M = N * N; 8 const int L = 11; 9 bool visit[N]; 10 int head[N]; 11 int mark[N]; 12 int n, m, p, e; 13 14 struct Edge 15 { 16 int v, next; 17 } edge[M]; 18 19 struct Hobby 20 { 21 char like[L], dislike[L]; 22 } hobby[N]; 23 24 void init() 25 { 26 e = 0; 27 memset( head, -1, sizeof(head) ); 28 } 29 30 void addEdge( int u, int v ) 31 { 32 edge[e].v = v; 33 edge[e].next = head[u]; 34 head[u] = e++; 35 } 36 37 int dfs( int u ) 38 { 39 for ( int i = head[u]; i != -1; i = edge[i].next ) 40 { 41 int v = edge[i].v; 42 if ( !visit[v] ) 43 { 44 visit[v] = true; 45 if ( mark[v] == -1 || dfs( mark[v] ) ) 46 { 47 mark[v] = u; 48 mark[u] = v; 49 return 1; 50 } 51 } 52 } 53 return 0; 54 } 55 56 int hunagry() 57 { 58 memset( mark, -1, sizeof(mark) ); 59 int res = p; 60 for ( int i = 1; i <= p; i++ ) 61 { 62 if ( mark[i] != -1 ) continue; 63 memset( visit, 0, sizeof(visit) ); 64 res -= dfs(i); 65 } 66 return res; 67 } 68 69 int main() 70 { 71 while ( scanf("%d%d%d", &n, &m, &p) != EOF ) 72 { 73 init(); 74 for ( int i = 1; i <= p; i++ ) 75 { 76 scanf("%s%s", hobby[i].like, hobby[i].dislike); 77 for ( int j = i - 1; j > 0; j-- ) 78 { 79 if ( strcmp( hobby[i].like, hobby[j].dislike ) == 0 80 || strcmp( hobby[j].like, hobby[i].dislike ) == 0 ) 81 { 82 addEdge( i, j ); 83 addEdge( j, i ); 84 } 85 } 86 } 87 printf("%d\n", hunagry()); 88 } 89 return 0; 90 }
时间: 2024-11-08 01:07:34