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 }

 

posted @ 2014-11-05 15:41  Naturain  阅读(149)  评论(0)    收藏  举报