Poj--3692(最大独立集)
2014-11-05 15:39:52
思路:这题要选的是相互认识的人,那么我们把相互不忍识的girls和boys连边,这样就能转化成最大独立集问题了,最大独立集里的人一定相互认识,因为不认识的都连过边了,而最大独立集的任意两点不可能有连边。
1 /************************************************************************* 2 > File Name: 3692.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 05 Nov 2014 03:30:30 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 210; 27 28 int G,B,M; 29 int g[maxn][maxn]; 30 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt; 31 int used[maxn],mat[maxn]; 32 33 void Init(){ 34 memset(g,0,sizeof(g)); 35 memset(first,-1,sizeof(first)); 36 ecnt = 0; 37 } 38 39 void Add_edge(int u,int v){ 40 next[++ecnt] = first[u]; 41 ver[ecnt] = v; 42 first[u] = ecnt; 43 } 44 45 bool find(int p){ 46 for(int i = first[p]; i != -1; i = next[i]){ 47 int v = ver[i]; 48 if(used[v] == 0){ 49 used[v] = 1; 50 if(mat[v] == 0 || find(mat[v])){ 51 mat[v] = p; 52 return true; 53 } 54 } 55 } 56 return false; 57 } 58 59 int Hungary(){ 60 int ans = 0; 61 memset(mat,0,sizeof(mat)); 62 for(int i = 1; i <= G; ++i){ 63 memset(used,0,sizeof(used)); 64 if(find(i)) ++ans; 65 } 66 return ans; 67 } 68 69 int main(){ 70 int a,b,Case = 0; 71 while(scanf("%d%d%d",&G,&B,&M) != EOF){ 72 if(G == 0 && B == 0 && M == 0) 73 break; 74 Init(); 75 for(int i = 1; i <= M; ++i){ 76 scanf("%d%d",&a,&b); 77 g[a][b] = 1; 78 } 79 for(int i = 1; i <= G; ++i){ 80 for(int j = 1; j <= B; ++j) if(!g[i][j]){ 81 Add_edge(i,j); 82 } 83 } 84 printf("Case %d: %d\n",++Case,G + B - Hungary()); 85 } 86 return 0; 87 }

浙公网安备 33010602011771号