Poj--3041(二分图最大匹配,最小点覆盖)
2014-11-04 22:57:48
思路:König定理:最小覆盖点数==最大匹配数。证明:推荐Matrix67(虽然还没全看懂QAQ)http://www.matrix67.com/blog/archives/116
1 /************************************************************************* 2 > File Name: 3041.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Tue 04 Nov 2014 09:37:54 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 = 510; 27 28 int n,k; 29 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt; 30 int mat[maxn],used[maxn]; 31 32 void Init(){ 33 memset(first,-1,sizeof(first)); 34 ecnt = 0; 35 } 36 37 void Add_edge(int u,int v){ 38 next[++ecnt] = first[u]; 39 ver[ecnt] = v; 40 first[u] = ecnt; 41 } 42 43 bool find(int p){ 44 for(int i = first[p]; i != -1; i = next[i]){ 45 int v = ver[i]; 46 if(used[v] == 0){ 47 used[v] = 1; 48 if(mat[v] == 0 || find(mat[v])){ 49 mat[v] = p; 50 return true; 51 } 52 } 53 } 54 return false; 55 } 56 57 int Hungary(){ 58 int ans = 0; 59 for(int i = 1; i <= n; ++i){ 60 memset(used,0,sizeof(used)); 61 if(find(i)) ++ans; 62 } 63 return ans; 64 } 65 66 int main(){ 67 int a,b; 68 while(scanf("%d%d",&n,&k) != EOF){ 69 Init(); 70 for(int i = 1; i <= k; ++i){ 71 scanf("%d%d",&a,&b); 72 Add_edge(a,b); 73 } 74 printf("%d\n",Hungary()); 75 } 76 return 0; 77 }

浙公网安备 33010602011771号