zoukankan      html  css  js  c++  java
  • Algorithm --> 二分图最大匹配

     匈牙利算法

    二分图把一个图的顶点划分为两个不相交集 U  和 V ,使得每一条边都分别连接U 、 V  中的顶点。如果存在这样的划分,则此图为一个二分图。

    Bipartite1

    匹配:在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点。例如,图 3、图 4 中红色的边就是图 2 的匹配。 

     Bipartite Graph(1)  Bipartite Graph(2)  Matching  Maximum Matching

    匹配点匹配边未匹配点非匹配边:例如图 3 中 1、4、5、7 为匹配点,其他顶点为未匹配点;1-5、4-7为匹配边,其他边为非匹配边。

    最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。图4 是一个最大匹配,它包含 4 条匹配边。

    完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。图4 是一个完美匹配。显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。但并非每个图都存在完美匹配。

    交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边...形成的路径叫交替路。

    增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。例如,图 5 中的一条增广路如图 6 所示(图中的匹配点均用红色标出):

    5

     

                                             6

    代码:

     #include<iostream>
     #include<cstdio>
     #include<cstring>
     using namespace std;
     
     const int MaxN=100;
     
     int N,M;
     int Ans;
     int link[MaxN];
     bool cover[MaxN];
     bool Map[MaxN][MaxN];
     
     void init()
     {
         int i,x,y;
         scanf("%d%d",&N,&M);
         memset(Map,false,sizeof(Map));
         for(i=1;i<=M;++i)
         {
             scanf("%d%d",&x,&y);
             Map[x][y]=true;
         }
     }
     bool Find(int i)
     {
         int j;
         for(j=1;j<=N;++j)
             if(Map[i][j] && !cover[j])
             {
                 cover[j]=true;
                 if(!link[j] || Find(link[j]))
                 {
                     link[j]=i;
                     return true;
                 }
             }
         return false;
     }
     void solve()
     {
         int i;
         memset(link,0,sizeof(link));
         for(i=1;i<=N;++i)
         {
             memset(cover,false,sizeof(cover));
             Find(i);
         }
     }
     void print()
    {
         int i;
         Ans=0;
         for(i=1;i<=N;++i)
             if(link[i])
                 Ans++;
         printf("%d
    ",Ans);
         for(i=1;i<=N;++i)
             if(link[i])
                 printf("%d %d
    ",link[i],i);
     }
     int main()
     {
         init();
         solve();
         print();
         return 0;
    }


    例一:二分图

    给定一个图(可能为非联通图),将其二分,得到两个数组,输出其中某个数组的个数和顶点?

    输入用例(二分图检测):

    9 8
    4 1 1 2 2 3 7 2 1 5 8 4 5 8 8 9
    7 10
    1 2 2 3 1 6 4 6 2 4 2 7 2 5 6 7 3 5 5 7
    15 22
    7 3 9 8 1 10 1 15 8 3 9 11 5 12 8 4 1 4 13 7 14 11 12 8 6 8 2 8 15 8 7 15 8 10 14 5 8 13 11 2 8 14 6 5
    21 26
    8 7 10 21 5 4 18 11 5 12 10 6 9 3 15 16 16 10 17 11 12 2 20 3 7 2 19 4 13 4 13 10 15 6 12 19 8 3 7 20 14 11 9 11 4 21 17 3 12 1 7 1
    40 57
    6 22 22 23 36 21 18 19 4 5 33 36 19 16 5 2 36 38 17 37 11 12 30 19 11 21 5 39 25 27 29 22 11 28 4 10 10 17 37 1 33 11 8 37 10 1 14 10 36 35 24 19 9 26 36 31 27 37 34 6 11 2 16 9 38 34 7 37 5 12 23 19 34 31 29 34 34 35 5 28 13 9 22 3 32 37 34 3 30 9 40 11 8 25 20 19 20 9 22 18 5 14 39 10 32 10 36 40 15 9 22 24 7 25
    50 49
    23 12 49 43 18 12 18 25 22 29 27 8 6 33 17 34 20 33 5 3 8 25 3 21 37 27 41 19 28 5 15 44 34 49 27 4 13 33 22 30 31 35 1 18 16 9 48 25 27 6 5 7 44 39 42 36 11 35 3 50 27 31 36 32 2 8 16 22 47 26 28 24 6 16 5 10 15 38 45 18 5 6 14 13 9 40 28 36 5 34 44 6 6 26 46 3 41 33
    50 1225
    12 26 26 36 49 31 21 3 30 28 21 48 43 6 48 20 15 45 16 24 37 40 35 20 30 9 49 16 31 48 37 47 29 18 44 28 36 25 38 43 12 16 32 45 31 46 34 38 29 30 42 29 27 20 40 16 31 25 14 43 2 10 10 3 39 44 43 17 44 26 18 19 4 17 50 11 14 9 35 9 6 40 25 27 38 20 1 49 3 24 21 44 36 22 1 47 50 7 21 4 3 26 12 50 25 42 48 26 23 27 16 38 22 20 36 10 5 41 29 32 42 1 26 17 33 32 26 31 21 16 48 37 35 41 21 33 31 3 9 10 35 36 48 13 16 30 41 45 26 14 26 25 36 42 10 14 21 45 6 28 44 31 15 1 6 32 6 27 45 10 20 34 23 20 39 43 7 23 13 49 25 48 11 8 4 5 29 4 21 32 25 46 46 19 22 9 33 22 38 22 34 36 6 20 30 46 31 32 31 41 27 16 14 7 2 6 48 49 50 8 13 20 27 21 10 16 33 39 1 34 9 25 13 29 50 41 29 36 12 22 1 18 12 35 13 30 5 16 45 39 27 50 25 7 46 40 37 39 3 13 12 9 23 50 33 24 37 36 3 22 39 14 33 2 18 23 42 37 29 27 8 48 5 8 50 6 40 24 26 49 14 18 36 8 46 38 7 46 11 46 11 3 6 11 41 28 23 48 17 5 12 40 15 44 8 38 21 6 7 21 49 36 2 21 4 49 28 20 39 32 25 41 11 31 30 47 32 16 17 22 9 45 38 21 16 34 30 15 11 9 38 9 10 37 23 3 18 27 4 8 32 27 50 37 24 35 29 10 25 2 2 27 10 23 36 1 1 41 41 6 14 36 23 15 21 49 48 4 5 37 14 27 44 1 16 6 50 39 38 42 21 19 48 5 29 47 39 7 14 42 35 38 35 14 39 12 48 14 37 45 15 28 29 6 10 6 7 12 35 18 42 24 13 37 32 35 38 27 11 22 41 38 15 7 21 1 43 10 41 9 35 23 32 24 38 29 18 38 47 38 50 24 33 13 42 26 13 23 40 45 27 12 16 8 35 5 25 44 26 22 41 24 50 25 45 13 8 40 40 5 43 46 36 13 6 18 37 6 14 31 9 15 14 23 23 33 48 33 17 50 24 37 45 46 18 2 13 11 20 8 13 22 33 4 19 43 11 37 7 29 19 35 28 23 7 27 16 4 2 16 30 7 18 47 50 32 33 26 11 23 25 34 9 27 48 12 36 50 31 1 25 29 16 15 32 36 32 48 19 37 4 22 20 18 14 5 25 37 36 46 49 43 24 23 1 25 34 14 31 6 4 18 21 10 24 30 9 42 4 36 25 15 12 28 14 28 37 18 7 47 44 27 13 27 1 10 36 41 34 40 2 36 38 10 50 35 24 6 26 20 45 50 17 16 9 13 14 46 39 34 5 28 13 34 4 39 33 46 45 36 4 47 45 19 13 6 1 50 9 5 26 32 42 8 23 42 2 41 47 20 13 46 16 36 49 3 25 40 19 47 32 38 4 15 4 7 2 15 15 38 15 8 8 14 36 39 45 33 44 10 18 39 6 25 46 8 4 40 41 34 35 22 40 48 2 40 31 27 12 24 26 15 28 25 1 38 33 43 21 24 30 8 11 26 28 50 6 30 30 11 50 3 29 43 31 10 28 4 21 43 48 41 48 50 22 10 6 45 30 27 5 24 28 2 1 20 16 35 17 28 16 26 15 43 24 15 42 3 41 19 4 32 44 12 18 24 31 28 38 23 22 49 32 44 2 44 28 47 35 13 14 25 1 30 22 44 19 16 22 47 10 49 9 48 48 10 12 15 32 12 40 31 8 19 1 33 18 15 43 41 15 5 39 25 35 25 45 22 12 3 37 21 47 49 8 34 20 25 7 36 30 3 43 25 40 19 40 49 5 22 25 47 31 13 36 44 15 41 6 22 44 47 2 8 22 31 29 34 38 3 15 48 39 21 21 18 19 1 23 45 46 2 9 32 21 40 42 47 5 32 43 24 43 5 45 25 25 24 44 40 3 46 46 24 47 12 7 37 31 36 11 10 29 49 20 12 3 37 28 39 35 42 3 27 9 37 26 5 36 48 15 42 41 47 25 32 28 13 29 22 14 15 34 5 28 49 32 15 19 49 16 44 44 14 31 34 22 7 50 40 47 3 18 41 7 19 20 41 34 24 12 11 11 41 26 24 7 17 8 24 18 10 36 18 28 33 19 27 9 31 4 43 22 48 24 27 3 7 39 30 16 29 30 49 1 40 21 15 4 31 8 13 5 45 22 21 29 40 9 40 48 43 3 25 14 3 48 19 41 27 42 50 29 24 18 49 30 41 2 31 18 30 29 15 16 20 47 14 27 35 24 22 30 32 2 14 42 31 38 13 8 44 24 10 43 47 36 33 38 30 17 39 8 28 32 2 19 29 24 48 32 34 46 18 12 14 19 25 6 33 49 27 43 27 7 18 25 17 4 25 46 35 10 13 41 44 35 8 46 5 41 32 7 13 47 11 36 9 28 10 5 25 35 48 42 2 9 46 17 33 1 8 49 39 35 43 50 15 14 45 2 7 44 7 41 8 27 28 10 32 34 42 21 5 46 10 18 13 14 6 9 50 12 6 1 17 44 17 42 30 2 43 33 11 44 11 16 14 9 6 20 32 18 16 13 39 4 19 23 5 43 1 35 11 2 11 21 41 26 9 36 5 26 2 12 8 15 33 41 39 20 39 40 17 47 32 49 37 32 1 32 46 8 39 14 30 23 43 21 36 28 18 44 34 46 4 13 40 14 4 46 27 44 42 38 45 18 50 49 25 47 34 10 26 37 14 3 9 29 44 15 34 3 39 23 19 44 19 1 5 10 17 38 25 11 32 38 19 33 44 21 8 36 43 41 42 30 34 50 19 7 24 34 3 20 31 20 36 17 45 9 28 33 14 6 34 10 8 24 47 11 24 1 4 40 18 42 39 26 19 8 43 44 38 48 47 24 4 17 46 24 2 8 9 12 30 3 36 37 31 27 48 3 2 42 16 29 12 28 29 45 1 1 27 46 1 11 21 2 47 13 5 32 22 6 1 19 5 33 40 37 2 42 49 28 24 19 20 35 49 20 50 31 50 22 27 29 26 20 7 42 18 48 34 6 23 5 3 34 49 1 3 38 50 25 10 45 49 21 20 5 50 13 41 26 40 38 24 1 14 5 2 37 15 8 31 50 47 7 40 43 26 10 50 29 48 7 42 36 40 15 49 6 49 10 15 1 35 18 17 46 26 18 9 23 25 39 11 28 34 3 16 8 6 28 11 9 47 36 23 24 49 42 28 23 31 7 28 34 27 35 17 37 33 38 6 18 45 48 38 8 23 6 7 29 2 17 13 28 40 21 23 14 32 35 34 13 21 36 12 41 29 29 37 47 40 7 49 17 14 46 41 30 5 28 22 35 28 48 17 16 31 19 2 47 46 36 27 37 35 13 43 4 44 28 21 38 28 48 7 15 47 1 7 22 42 45 7 27 10 48 46 5 39 33 47 20 11 20 29 38 7 34 50 30 2 9 34 20 43 2 35 11 38 32 28 47 6 43 34 1 22 47 35 21 9 12 5 48 11 19 6 36 19 19 39 5 47 21 50 21 14 31 39 50 4 33 5 29 35 32 17 17 6 30 21 40 27 32 7 28 36 17 42 16 43 48 39 20 33 25 30 39 24 42 45 45 27 24 17 12 10 13 50 27 42 19 15 45 48 23 47 46 37 25 12 1 39 29 8 21 31 17 49 3 20 30 40 17 20 24 1 33 29 37 27 25 22 23 29 38 26 11 42 6 36 31 24 35 40 7 43 45 3 43 50 16 33 9 19 40 20 15 35 7 26 43 45 20 14 45 20 16 50 48 42 26 13 20 15 40 42 45 44 35 26 45 8 38 39 22 34 13 15 39 6 4 3 21 34 2 13 16 23 24 19 9 1 16 28 31 33 4 45 41 40 37 23 25 13 21 42 19 12 7 8 9 23 32 43 19 42 21 25 42 43 33 7 27 17 9 17 30 20 40 39 29 21 13 32 28 46 8 47 30 17 39 29 39 9 37 38 5 27 9 16 43 18 21 35 34 33 20 2 15 11 27 39 45 16 8 25 45 35 49 46 45 2 9 49 44 13 14 19 48 18 12 13 37 20 35 10 41 22 2 48 16 13 48 1 49 8 20 10 30 45 50 22 2 12 4 10 17 41 2 1 6 46 16 39 43 30 2 23 30 35 34 26 20 49 33 41 39 2 20 46 15 39 44 24 32 23 26 30 6 4 14 41 49 23 46 29 34 17 38 2 36 11 20 42 13 24 18 34 19 30 16 48 28 26 17 21 31 30 13 4 41 12 34 10 1 37 27 47 19 17 37 44 23 26 1 28 9 7 37 8 5 6 41 7 20 44 38 14 24 20 48 3 30 10 1 29 21 47 30 44 20 4 22 23 43 11 36 24 39 10 10 7 46 44 16 37 38 33 36 15 17 36 9 33 44 35 44 6 42 4 1 26 22 8 10 33 33 8 27 15 14 11 5 49 1 13 11 16 11 19 49 41 38 36 50 26 20 5 34 46 48 30 45 47 2 50 29 50 47 16 19 28 23 1 17 29 41 16 49 11 33 19 19 10 43 12 11 25 22 43 39 26 45 12 43 37 9 4 35 39 10 47 17 15 41 4 50 46 29 14 31 12 16 46 30 36 12 46 11 40 43 40 49 14 30 4 3 35 26 18 19 32 20 9 12 4 30 33 27 8 24 14 37 28 25 16 40 14 17 12 8 26 2 34 15 6 29 3 34 4 10 5 12 18 4 11 5 29 15 40 43 28 5 38 32 49 13 14 42 12 23 30 45 29 49 33 11 34 8 32 13 19 46 15 27 11 41 23 33 25 28 48 23 17 3 33 44 49 25 18 11 7 37 30 43 9 12 23 47 13 1 12 23 40 23 44 24 9 50 14 46 39 3 32 23 34 44 3 1 16 33 35 22 46 4 2 31 47 42 32 40 3 31 7 8 17 4 27 35 31 4 35 36 47 31 45 19 3 7 35 17 3 46 23 26 37 12 49 27 26 18 44 12 38 42 5 6 35 46 21 34 19 11 1 22 2 5 18 4 38 22 16 9 29 42 13 23 39 48 44 31 5 12 37 7 16 22 40 2 17 44 5 40 38 47 26 11 29 4 26 6 3 21 12 9 44 33 18 28 3 33 50 18 22 31 17 37 34 41 26 17 38 3 43 45 11 18 31 10 41 19 22 42 33 49 38 45 24 43 44 47 17 37 17 40 32 37 4 22 30 4 23 39 22 27 33 31 19 31 15 15 22 29 31 18 32 9 2 41 37 5 11 5 7 26 6 34 45 18 8 32 37 49 50 12 34 30 50 33 12 31 38 49 2 50 44 26 45 42 6 46 42 10 40 47 39 3 8 26 21 31 43 37 22 42 10 17 11 22 14 45 28 41 3 11 18 3 18 7 34 15 3 48 6
    30 31
    2 15 11 4 26 9 5 16 5 6 23 12 30 10 22 21 19 6 21 28 20 14 16 2 17 24 27 14 25 26 13 22 7 29 22 8 17 1 24 20 3 18 23 28 11 18 4 25 30 8 10 15 1 9 19 29 7 12 13 3 8 27
    50 602
    13 23 31 12 21 36 19 40 24 16 3 23 43 23 10 24 50 29 20 39 2 46 9 4 25 6 37 45 4 31 39 37 41 13 34 22 13 17 44 39 27 8 47 49 9 32 40 20 19 15 18 42 14 34 18 17 46 34 25 11 38 32 16 13 25 36 41 21 11 13 31 48 25 5 18 1 44 12 18 29 45 9 4 19 3 30 31 8 18 5 50 41 20 8 36 5 47 23 13 10 40 31 9 38 10 50 36 33 35 10 44 14 33 43 10 43 43 11 49 36 24 6 4 7 37 27 20 34 7 2 18 16 8 37 49 16 32 45 50 24 42 33 12 14 41 35 48 32 21 47 23 6 31 39 36 18 31 27 49 25 7 15 6 3 24 47 7 46 42 17 44 9 42 35 38 15 47 41 28 38 11 21 14 15 28 27 33 10 11 29 8 28 25 29 8 4 31 14 25 42 27 48 46 32 16 10 34 32 16 11 33 13 11 6 35 1 45 46 16 33 48 39 29 5 45 22 24 11 40 34 37 15 28 14 19 8 45 34 45 8 47 33 38 27 40 8 8 12 37 46 7 8 6 43 45 19 16 50 3 18 12 40 16 1 1 17 28 12 8 26 24 43 50 35 9 8 11 41 37 9 49 33 17 16 33 35 45 15 23 50 49 21 24 30 5 13 22 31 12 34 46 48 9 26 42 43 33 30 49 6 43 16 20 2 5 42 4 12 49 10 3 16 7 40 7 26 19 26 11 47 41 49 22 37 4 37 41 16 39 2 50 43 12 9 11 5 45 44 1 47 26 34 45 48 23 49 17 21 7 28 11 17 12 26 41 6 15 22 9 15 48 7 11 10 3 25 15 39 4 26 10 21 22 19 40 26 32 12 9 7 38 31 37 26 14 40 46 31 22 26 3 33 42 29 9 46 5 21 42 16 25 10 39 12 50 11 41 30 46 28 14 20 39 19 50 47 16 30 23 18 40 28 31 34 50 17 40 45 1 41 32 19 15 26 40 32 22 8 30 47 24 21 34 15 24 3 29 10 44 46 29 47 19 38 25 47 38 8 49 17 36 42 11 35 45 2 9 2 4 2 43 18 27 2 41 25 27 44 16 6 27 45 37 28 22 39 3 36 19 34 5 43 29 41 13 50 2 8 48 38 29 24 21 30 42 3 5 49 48 37 4 22 42 13 20 28 6 42 28 45 47 10 23 33 42 24 39 9 50 5 23 41 30 36 41 18 2 38 32 2 6 33 35 3 17 6 32 31 46 4 38 45 15 28 42 47 45 4 14 7 43 49 37 32 43 17 17 30 24 1 3 11 20 37 11 49 27 32 48 15 40 39 19 7 47 36 23 29 43 35 10 5 3 21 37 44 13 24 43 41 24 36 1 11 13 3 30 29 32 44 18 11 4 40 2 34 12 2 2 37 35 49 33 11 28 2 36 13 27 20 48 26 24 18 36 50 1 3 27 12 50 42 20 12 17 35 12 10 31 37 15 40 20 7 7 45 9 20 17 24 40 38 21 6 27 46 9 34 36 17 19 12 43 36 4 27 28 26 26 45 42 30 41 10 7 34 30 35 27 39 1 5 23 5 18 21 39 38 44 19 20 46 17 29 2 14 14 4 31 28 41 42 25 24 2 44 24 5 32 14 48 2 39 46 38 34 14 22 39 28 7 22 34 28 21 16 21 23 12 22 25 43 32 4 41 24 8 48 12 46 22 32 1 49 8 14 41 36 26 46 3 43 5 30 30 50 17 33 28 19 19 46 5 16 23 25 30 6 20 4 16 35 22 38 34 37 4 44 49 50 22 27 29 36 25 17 6 18 46 40 15 27 49 24 48 9 37 7 31 20 33 25 19 48 38 7 26 31 25 35 38 44 26 32 40 9 1 33 18 30 27 14 42 10 1 10 49 30 15 46 31 15 46 8 33 41 39 8 27 7 41 5 37 40 49 42 4 34 14 37 14 38 23 16 16 29 7 31 17 23 6 1 23 36 28 22 9 31 11 23 40 44 18 13 30 1 4 39 6 50 48 22 19 14 23 10 1 23 4 48 33 24 44 34 30 23 33 29 25 30 35 23 35 36 43 13 5 35 48 34 45 39 28 48 42 11 25 21 1 36 19 2 6 10 17 3 2 31 47 16 29 49 24 35 20 44 1 25 16 25 26 14 7 44 40 27 6 29 49 3 7 32 21 29 9 28 1 29 5 47 18 33 40 2 42 1 28 44 29 43 20 15 14 48 23 24 6 35 44 26 30 43 39 7 7 12 22 40 32 15 3 10 45 14 14 39 33 21 18 35 21 1 15 12 1 43 12 45 20 26 35 29 22 2 6 47 35 47 4 15 38 4 3 5 40 48 38 26 44 15 9 27 20 22 20 32 30 11 13 6 48 44 10 30 5 33 41 3 8 15 21 13 48 12 12 38 10 17 2 26 38 20 3 29 6 5 6 36 47 13 27 19 9 22 32 28 20 19 19 9 14 9 26 39 13 29 23 42 43 21 18 49 22 44 13 49 36 10 8 44 38 37 50 33 20 48 31 45 25 50 35 21 8 34 27 43 17 47 42 21 31 19 34 27 11 36 2 15 50 18 5 17 32 8 44 31 38 46 12 37 13 25 39 32 28 4 35 13 50 1 30 13 1 13 47 18 19 37 46 14 18 25 16 36 3 50 22 46 27 26 18 10 3 47 45 20 50 21 34 39 43 47 41 17
    20 38
    7 9 6 20 6 2 2 19 8 6 11 19 3 4 8 2 7 10 1 5 2 11 2 15 17 16 15 18 12 20 17 2 2 3 2 7 12 2 2 9 20 2 14 16 4 2 2 1 14 13 16 2 2 5 18 2 10 2 17 3 13 11 18 1 13 2 10 12 15 9 8 19 4 5 14 2
    50 143
    37 25 8 11 17 11 49 17 15 17 5 48 38 17 35 17 4 44 18 1 38 42 13 8 20 31 17 21 48 32 17 10 10 34 49 47 17 43 47 8 9 17 8 17 17 5 47 22 47 45 45 40 47 3 39 17 41 16 7 47 47 50 40 28 5 30 40 47 23 42 11 28 23 17 17 7 47 13 17 44 47 23 45 17 47 20 47 43 17 3 27 17 17 12 48 47 29 47 47 11 18 43 25 26 25 17 46 47 9 15 17 20 49 24 26 47 30 22 17 33 2 47 47 37 17 31 17 30 14 46 7 36 47 21 47 33 17 48 31 47 34 49 27 47 41 47 38 47 26 17 47 34 39 47 36 47 4 47 12 14 17 16 15 47 3 20 44 47 35 47 17 6 22 17 17 41 34 17 18 47 17 42 14 17 47 42 18 17 17 32 12 47 40 17 27 29 23 7 17 4 36 17 9 13 39 41 43 50 16 33 19 47 6 47 19 3 17 13 45 21 32 39 27 24 47 10 25 47 36 37 47 32 26 2 15 50 1 46 30 47 38 21 47 14 17 1 17 37 24 47 47 1 24 17 29 33 12 31 47 9 17 29 47 28 17 19 6 4 17 28 5 47 50 17 16 47 2 17 2 6 10 19 17 46 44 35
    View Code

    算法代码:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define MAX 1001
    
    int path[MAX][MAX] = {0}; 
    int c[MAX] = {0};
    int group[MAX] = {0};
    int count = 0;
    int N, E;
    int value[3] = {0, 2, 1};
    int partition(int start)    //给每个点分组,存到group[]
    {
        for(int i = 0; i < c[start]; i++)
        {
            int city = path[start][i];
            if(group[city] != 0)
            {
                if(group[city] == group[start])return 0;  //相邻两个点分组一样,则返回0,不是二分图
            }
            else
            {
                group[city] = value[group[start]];
                if (group[city] == 1)count++;
                if(!partition(city))return 0;
            }
        }
    
        return 1;
    }
    
    int getNoGroup(int * pt)
    {
        for (int i = 1; i <= N; i++)
        {
            if (!group[i])
            {
                *pt = i;
                return 1;
            }
        }
    
        return 0;
    }
    
    int main(void)
    {
        freopen("input3.txt", "r", stdin);
        //freopen("output.txt", "w", stdout);
    
        for(int test_case = 1; test_case <= 10; test_case++)
        {
            scanf("%d %d
    ", &N, &E);
            for(int i = 0; i < E; i++)
            {
                int pt1, pt2;
                scanf("%d %d", &pt1, &pt2);
                path[pt1][c[pt1]++] = pt2;
                path[pt2][c[pt2]++] = pt1;
            }
    
            int start = 0;
            bool errorFlag = false;   //判断是否是二分图
            while(getNoGroup(&start))   //当非连通图的时候,也能遍历到
            {
                group[start] = 2;
                if(!partition(start))
                {
                    errorFlag = true;
                    break;
                }
            }
    
            if(errorFlag)printf("#%d -1
    ", test_case);
            else
            {
                printf("#%d %d", test_case, count);
                for(int i = 1; i <= N; i++)if(group[i] == 1)printf(" %d", i);
                printf("
    ");
            }
    
            memset(group, 0, MAX*4);
            memset(path, 0, MAX*MAX*4);
        }
    
        return 0;
    }

    例二:圣诞礼物

    给定人数和礼物数量,接下来给出每个人喜欢的礼物的编号,求最大匹配?

    输入用例(二分图最大匹配):

    5
    3 4
    3 1 2 3
    1 2
    2 1 3
    
    10 10
    3 1 7 8
    3 5 9 10
    3 3 6 10
    3 5 6 9
    3 4 5 8
    3 1 8 10
    2 3 8
    2 4 8
    3 2 3 6
    3 4 6 7
    
    15 15
    2 12 13
    2 1 11
    2 8 12
    2 7 9
    2 12 15
    2 6 8
    2 5 12
    2 12 14
    2 10 12
    2 3 4
    2 11 13
    2 10 11
    2 8 15
    2 8 15
    2 13 14
    
    50 50
    2 12 30
    2 18 43
    2 11 46
    2 30 37
    2 25 28
    2 2 49
    2 26 36
    2 3 27
    2 23 50
    2 2 50
    2 17 22
    2 47 48
    2 8 11
    2 41 49
    2 6 18
    2 18 43
    2 36 48
    2 8 36
    2 22 31
    2 6 37
    2 39 49
    2 5 25
    2 25 31
    2 24 27
    2 4 27
    1 25
    2 21 43
    2 1 23
    2 22 31
    2 37 42
    2 35 40
    2 5 37
    2 20 40
    2 1 45
    2 11 32
    2 6 10
    2 10 20
    2 34 44
    2 10 40
    2 18 44
    2 37 42
    2 19 29
    2 13 41
    2 30 44
    2 13 21
    2 2 30
    2 5 34
    2 25 38
    2 23 33
    2 25 34
    1 0
    0
    
    5 5
    1 1
    1 2
    1 3
    1 4
    1 5
    View Code

    算法代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <vector>
    using namespace std;
    
    #define MAX 401
    
    int map[MAX][MAX] = { 0 }; //第i个人的每个礼物的编号
    int c[MAX] = { 0 };        //第i个人一共可能连多少个礼物
    int check[MAX] = { 0 };    //表示当前第i个人已经遍历过的礼物编号
    int matching[MAX] = { 0 }; //礼物和人匹配的状态
    
    
    bool dfs(int u)
    {
        for (int i = 0; i < c[u]; i++) 
        {
            int v = map[u][i];
            if (!check[v])
            {
                check[v] = true;
                if(matching[v] == 0 || dfs(matching[v]))
                {
                    matching[v] = u;
                    matching[u] = v;
                    return true;
                }
            }
        }
        return false; 
    }
    
    int main(int argc, char** argv)
    {
        freopen("input.txt", "r", stdin);
        int case_max;
        scanf("%d
    ", &case_max);
        for(int case_num = 0; case_num < case_max; case_num++)
        {
            int personCnt, giftCnt;
            scanf("%d %d
    ", &personCnt, &giftCnt);
            for(int i = 1; i <= personCnt; i++)
            {
                int favoriteCnt;
                scanf("%d ", &favoriteCnt);
                for(int j = 1; j <= favoriteCnt; j++)
                {
                    int favorite;
                    scanf("%d", &favorite);
                    //map[i].push_back(personCnt+favorite);
                    map[i][c[i]++] = personCnt + favorite;
                    map[personCnt + favorite][c[personCnt + favorite]++] = i;
                }
            }
    
            int result = 0;
            for(int i = 1; i <= personCnt; i++)
            {
                if (matching[i] == 0) 
                {
                    memset(check, 0, sizeof(check));
                    if(dfs(i))result++;
                }
            }
    
            printf("%d
    ", result);
    
            memset(map, 0, sizeof(int)*MAX*MAX);
        }
    } 
  • 相关阅读:
    网站备份list
    vnc checklist
    appnode iptables 规则后面覆盖前面的
    Appnode + Discuz checklist
    解决WORD文档无法显示链接的图像问题
    应用容器Application container
    要研究的内容
    转 Flex MXML编译成AS类
    Flex文件结构
    int a
  • 原文地址:https://www.cnblogs.com/jeakeven/p/4633577.html
Copyright © 2011-2022 走看看