uvalive 3415 Guardian Of Decency
题意:
有一个老师想组织学生出去旅游,为了避免他们之间有情侣产生,他制定了一系列的条件,满足这些条件之一,那么这些人理论上就不会成为情侣:
身高相差40cm;性别相同;喜欢的音乐风格不同;最喜欢的运动相同。
给出若干个学生的身高,性别,喜欢的音乐风格和喜欢的运动,问最多有多少人可以出去。
思路:
对于两个人,如果以上所有条件都不满足,那么就在他们之间连边,说明他们不能同时去。
问题就转化成了求一个二分图的最大独立集。(独立集是两两之间不存在边的点的集合,最大顾名思义)
最大独立集 = 点数- 最小点覆盖 = 点数 – 最大匹配
匈牙利算法,复杂度O(n^3)。
代码:
1 #include <stdio.h> 2 #include <iostream> 3 #include <string> 4 #include <string.h> 5 #include <vector> 6 using namespace std; 7 8 const int N = 505; 9 10 vector<int> g[N]; 11 int link[N]; 12 bool vis[N]; 13 14 struct node 15 { 16 int hei; 17 string sex,music,sport; 18 19 node(int a,string b,string c,string d) 20 { 21 hei = a; 22 sex = b; 23 music = c; 24 sport = d; 25 } 26 }; 27 28 vector<node> ns; 29 30 bool dfs(int u) 31 { 32 for (int i = 0;i < g[u].size();i++) 33 { 34 int v = g[u][i]; 35 36 if (!vis[v]) 37 { 38 vis[v] = 1; 39 40 if (link[v] == -1 || dfs(link[v])) 41 { 42 link[v] = u; 43 link[u] = v; 44 45 return true; 46 } 47 } 48 } 49 50 return false; 51 } 52 int solve(int n) 53 { 54 int cnt = 0; 55 56 memset(link,-1,sizeof(link)); 57 58 for (int i = 0;i < n;i++) 59 { 60 if (link[i] == -1) 61 { 62 memset(vis,0,sizeof(vis)); 63 if (dfs(i)) cnt++; 64 } 65 } 66 67 return cnt; 68 } 69 70 int mabs(int x) 71 { 72 return x >= 0 ? x : -x; 73 } 74 75 int main() 76 { 77 int t; 78 79 scanf("%d",&t); 80 81 while (t--) 82 { 83 int n; 84 85 scanf("%d",&n); 86 87 ns.clear(); 88 89 for (int i = 0;i < n;i++) 90 { 91 g[i].clear(); 92 int a; 93 string b,c,d; 94 95 cin >> a >> b >> c >> d; 96 97 ns.push_back(node(a,b,c,d)); 98 } 99 100 for (int i = 0;i < n;i++) 101 { 102 for (int j = i + 1;j < n;j++) 103 { 104 bool f = 0; 105 106 if (mabs(ns[i].hei - ns[j].hei) > 40) f = 1; 107 if (ns[i].sex == ns[j].sex) f = 1; 108 if (ns[i].music != ns[j].music) f = 1; 109 if (ns[i].sport == ns[j].sport) f = 1; 110 111 if (!f) 112 { 113 g[i].push_back(j); 114 g[j].push_back(i); 115 } 116 } 117 } 118 119 int ans = solve(n); 120 121 printf("%d\n",n - ans); 122 } 123 124 return 0; 125 }
康复训练中~欢迎交流!