POJ 1274 裸二分图匹配
题意:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶,告诉每头奶牛愿意产奶的牛棚编号,求出最多能分配到的牛栏的数量。
分析:直接二分图匹配;
1 #include<stdio.h>
2 #include<memory.h>
3
4 #define MAX 202
5 bool flag,visit[MAX]; //记录V2中的某个点是否被搜索过
6 int match[MAX]; //记录与V2中的点匹配的点的编号
7 int cow, stall; //二分图中左边、右边集合中顶点的数目
8 int head[MAX];
9
10 struct edge
11 {
12 int to,next;
13 }e[3000];
14 int index;
15
16 void addedge(int u,int v)
17 { //向图中加边的算法,注意加上的是有向边
18 //u为v的后续节点既是v---->u
19 e[index].to=v;
20 e[index].next=head[u];
21 head[u]=index;
22 index++;
23 }
24
25
26 // 匈牙利(邻接表)算法
27 bool dfs(int u)
28 {
29 int i,v;
30 for(i = head[u]; i != 0; i = e[i].next)
31 {
32 v = e[i].to;
33 if(!visit[v]) //如果节点v与u相邻并且未被查找过
34 {
35 visit[v] = true; //标记v为已查找过
36 if(match[v] == -1 || dfs(match[v])) //如果i未在前一个匹配M中,或者i在匹配M中,但是从与i相邻的节点出发可以有增广路径
37 {
38 match[v] = u; //记录查找成功记录,更新匹配M(即“取反”)
39 return true; //返回查找成功
40 }
41 }
42 }
43 return false;
44 }
45 int MaxMatch()
46 {
47 int i,sum=0;
48 memset(match,-1,sizeof(match));
49 for(i = 1 ; i <= cow ; ++i)
50 {
51 memset(visit,false,sizeof(visit)); //清空上次搜索时的标记
52 if( dfs(i) ) //从节点i尝试扩展
53 {
54 sum++;
55 }
56 }
57 return sum;
58 }
59
60 int main(void)
61 {
62 int i,j,k,ans,m;
63 while (scanf("%d %d",&cow, &stall)!=EOF)
64 {
65 memset(head,0,sizeof(head)); //切记要初始化
66 index = 1;
67 for (i = 1; i <= cow; ++i)
68 {
69 scanf("%d",&k);
70 for (j = 0; j < k; ++j)
71 {
72 scanf("%d",&m);
73 addedge(i , m);
74 }
75 }
76
77 ans = MaxMatch();
78 printf("%d\n",ans);
79 }
80 return 0;
81 }
人生就像心电图,想要一帆风顺,除非game-over