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
",ans);
79     }
80     return 0;
81 }
可以做模板

 

原文地址:https://www.cnblogs.com/ACMERY/p/4723283.html