zoukankan      html  css  js  c++  java
  • 模板——二分图匹配KM

    具体方法就不介绍了,详见 https://blog.csdn.net/sixdaycoder/article/details/47720471

    主要讲一些注意点:

    1:不直接将未匹配的y减小是因为要保证lx[i]+ly[j]>=w[i][j],证明详见上述博客

    2:因为多组数据,所有数组都记得清零

    3:dfs中坑了我20多次MLE……记得visx,visy数组都要更新

    4:这种做法仅限于每一个点都能被匹配的情况,若不能都匹配就要用网络流

    5:只有在值相等时才能赋值visy

    二分图匹配模板题:(值得思考)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int V,n,m,e;
     4 vector<int> v[1005];
     5 int vis[1005],match[1005];
     6  
     7 int init()
     8 {
     9     memset(match,-1,sizeof(match));
    10     scanf("%d%d%d%d",&V,&n,&m,&e);
    11     for(int i=1;i<=e;i++)
    12     {
    13         int x,y;
    14         scanf("%d%d",&x,&y); y+=n;
    15         v[x].push_back(y);
    16     }
    17 }
    18  
    19 int dfs(int u)
    20 {
    21     for(int i=0;i<(int)v[u].size();i++)
    22     {
    23         int p=v[u][i];
    24         if(vis[p]) continue;
    25         vis[p]=1;
    26         if(match[p]==-1||dfs(match[p])==1)
    27         {
    28             match[u]=p;
    29             match[p]=u;
    30             return 1;
    31         }
    32     }
    33     return 0;
    34 }
    35  
    36 int main()
    37 {
    38     int sum=0;
    39     init();
    40     for(int i=1;i<=n;i++)
    41     {
    42         if(match[i]==-1)
    43         {
    44             memset(vis,0,sizeof(vis));
    45             if (dfs(i)) sum++;
    46         }
    47     }
    48     printf("%d
    ",min(V+1,n+m-sum));
    49     return 0;
    50 }
    View Code

    KM模板题

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=305;
    const int inf=0X3f3f3f;
    
    int w[N][N];
    int n,ans=0;
    int lx[N],ly[N],match[N],slack[N];
    bool visx[N],visy[N];
    
    
    void init()
    {
        for(int i=0;i<n;i++) visy[i]=0;
        for(int i=0;i<n;i++) visx[i]=0;
    }
    
    bool dfs(int u)
    {
        int Delta;
        visx[u]=1;
        for(int v=0;v<n;++v)
        {
            if(visy[v]) continue;
            Delta=lx[u]+ly[v]-w[u][v];
            if(Delta==0)
            {
                visy[v]=1;
                if(match[v]==-1||dfs(match[v]))
                {
                    match[v]=u;
                    return true;
                }
            }
            else if(slack[v] > Delta)
                slack[v] = Delta;
        }
        return false;
    }
    
    void KM()
    {
        for(int x=0;x<n;++x)
        {
            for(int y=0;y<n;++y) slack[y]=inf; 
            while(true)
            {
                init();
                if(dfs(x)) break;
                int delta=inf;
                for(int j=0;j<n;++j) if(!visy[j]&&delta>slack[j]) delta=slack[j];
                for(int i=0;i<n;++i) if(visx[i]) lx[i]-=delta;
                for(int j=0;j<n;++j) 
                {
                    if(visy[j]) ly[j]+=delta;
                    else slack[j]-=delta;//important
                }
            }
        }
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            memset(match,-1,sizeof(match));
            memset(ly,0,sizeof(ly));
            for(int i=0;i<n;++i) match[i]=-1;
            for(int i=0;i<n;++i)
            {
                for(int j=0;j<n;++j)
                   {
                    scanf("%d",&w[i][j]);
                }
            }
            for(int i=0;i<n;++i)
            {
                lx[i]=-inf;
                for(int j=0;j<n;j++) if(lx[i]<w[i][j]) lx[i]=w[i][j];
            }
            KM();
        
            ans=0;
            for(int i=0;i<n;++i)
            {
                if(match[i]!=-1) ans+=w[match[i]][i];
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Cocos2d-x 学习笔记(11.1) MoveBy MoveTo
    Cocos2d-x 学习笔记(10) ActionInstant
    Cocos2d-x 学习笔记(9) Action 运行原理
    Cocos2d-x 学习笔记(8) ActionManager
    Cocos2d-x 学习笔记(7) 内存管理 Sprite SpriteFrame Texture2D
    Cocos2d-x 学习笔记(6) Sprite SpriteFrameCache Texture2D TextureCache
    常见串口术语区分
    串口调试
    Linux
    缓冲区
  • 原文地址:https://www.cnblogs.com/Forever-666/p/10980686.html
Copyright © 2011-2022 走看看