匈牙利算法 模版

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 }

你可能感兴趣的:(算法)