zoukankan      html  css  js  c++  java
  • 带权二分图的最大权匹配 KM算法模版

    带权二分图的最大权匹配 KM算法模版

    下面是kuangbin大神的模版,已通过西电oj1048的测试

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<string>
    #include<math.h>
    #include<cctype>
     
    using namespace std;
     
    typedef long long ll;
    const int maxn=550;
    const int INF=(1<<29);
    const double EPS=0.0000000001;
    const double Pi=acos(-1.0);
     
    int G[maxn][maxn];
    int m;
    int nx,ny;
    int link[maxn],lx[maxn],ly[maxn];
    int slack[maxn];
    bool visx[maxn],visy[maxn];
     
    bool dfs(int x)
    {
        visx[x]=1;
        for(int y=0;y<ny;y++){
            if(visy[y]) continue;
            int tmp=lx[x]+ly[y]-G[x][y];
            if(tmp==0){
                visy[y]=1;
                if(link[y]==-1||dfs(link[y])){
                    link[y]=x;
                    return true;
                }
            }
            else if(slack[y]>tmp) slack[y]=tmp;
        }
        return false;
    }
     
    int KM()
    {
        memset(link,-1,sizeof(link));
        memset(ly,0,sizeof(ly));
        for(int i=0;i<nx;i++){
            lx[i]=-INF;
            for(int j=0;j<ny;j++){
                if(G[i][j]>lx[i]) lx[i]=G[i][j];
            }
        }
        for(int x=0;x<nx;x++){
            for(int i=0;i<ny;i++) slack[i]=INF;
            while(1){
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                if(dfs(x)) break;
                int d=INF;
                for(int i=0;i<ny;i++){
                    if(!visy[i]&&d>slack[i]) d=slack[i];
                }
                for(int i=0;i<nx;i++){
                    if(visx[i]) lx[i]-=d;
                }
                for(int i=0;i<ny;i++){
                    if(visy[i]) ly[i]+=d;
                    else slack[i]-=d;
                }
            }
        }
        int res=0;
        for(int i=0;i<ny;i++){
            if(link[i]!=-1) res+=G[link[i]][i];
        }
        return res;
    }
     
    int main()
    {
        while(cin>>nx>>ny){
            memset(G,0,sizeof(G));
            cin>>m;
            while(m--){
                int u,v;
                scanf("%d%d",&u,&v);
                G[u][v]=1;
            }
            cout<<KM()<<endl;
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    二维vector初始化
    分类、目标检测、语义分割、实例分割的区别
    天池博客链接
    Windows pycocotools 安装
    解决 windows下pd.read_csv()读取文件失败
    解决 Anaconda中已有库 notebook却无法import
    win10下 修改Jupyter Notebook的默认路径
    C++ stack操作
    nginx启动错误
    Selenium的PageObject模式
  • 原文地址:https://www.cnblogs.com/--560/p/4554438.html
Copyright © 2011-2022 走看看