匈牙利算法 模版

poj 3692

View Code
 1 //POJ3692
 2 //匈牙利算法,二分图的最大匹配
 3 //最大完全数:最大完全子图中顶点的个数   最大完全数=原图的补图的最大独立数
 4 
 5 #include <iostream>
 6 #include <cstdio>
 7 #include <cstring>
 8 
 9 using namespace std;
10 
11 #define MAXN 210
12 
13 int nx,ny;
14 bool vis[MAXN];
15 int map[MAXN][MAXN];
16 int link[MAXN];//第y个点与第x相连
17 
18 bool dfs(int x)//寻找增广路
19 {
20     for(int y=1;y<=ny;y++ )//遍历右边点集
21     {
22         if(!vis[y] && map[x][y])
23         {
24             vis[y]=1;
25             if(link[y]==-1 || dfs(link[y]))//无配对 或 构成增广序列
26             {
27                 link[y]=x;
28                 return true;
29             }
30         }
31     }
32     return false;
33 }
34 
35 void maxmatch()
36 {
37     int ans=0;
38     memset(link,-1,sizeof(link));
39     for(int x=1;x<=nx;x++)//遍历左边点集
40     {
41         memset(vis,0,sizeof(vis));
42         if(dfs(x))
43             ans++;
44     }
45     printf("%d\n",nx+ny-ans);
46 }
47 
48 int main()
49 {
50     int a,b,m;
51     int cas=1;
52     while(scanf("%d%d%d",&nx,&ny,&m) && (nx+ny+m))
53     {
54         //memset(map,0,sizeof(map));//原图
55         memset(map,1,sizeof(map));//补图
56         while(m--)
57         {
58             scanf("%d%d",&a,&b);
59             //map[a][b]=1;
60             map[a][b]=0;
61         }
62         printf("Case %d: ",cas++);
63         maxmatch();
64     }
65     return 0;
66 }

poj 3041(dfs 模版)

View Code
 1 //最坏时间复杂度是o(n^3)
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 
 6 using namespace std;
 7 
 8 #define MAXN 505
 9 
10 int N,M;
11 bool vis[MAXN];
12 int map[MAXN][MAXN];
13 int link[MAXN];
14 bool can(int t)
15 {
16     for(int i=1;i<=N;i++)//对于集合N循环遍历
17     {
18         if(!vis[i] && map[t][i])//如果i与t有边&&i没被访问过
19         {
20             vis[i]=1;
21             if(link[i]==-1 || can(link[i]))//如果i与点集合gn中的点没有边,没有参与匹配的边则找到一条增广路,rpos到i存在没有参与匹配的边,而i到link[i]存在参与匹配的边然后往后找直到找到增广路,然后用M‘来代替M增加一条边
22             {
23                 link[i]=t;
24                 return true;
25             }
26         }
27     }
28     return false;
29 }
30 
31 void maxmatch()
32 {
33     int ans=0;
34     memset(link,-1,sizeof(link));
35     for(int i=1;i<=N;i++)//遍历一个点集
36     {
37         memset(vis,0,sizeof(vis));//每次都要将上一次走过的路径清空
38         if(can(i))
39             ans++;
40     }
41     printf("%d\n",ans);
42 }
43 
44 int main()
45 {
46     int a,b;
47     while(scanf("%d%d",&N,&M)==2)
48     {
49         memset(map,0,sizeof(map));
50         for(int i=0;i<M;i++)
51         {
52             scanf("%d%d",&a,&b);
53             map[a][b]=1;
54         }
55         maxmatch();
56     }
57     return 0;
58 }
原文地址:https://www.cnblogs.com/Missa/p/2703198.html