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!
  • 相关阅读:
    判断鼠标点击在div外时,更改背景图片
    CSS--border边框颜色渐变
    实验一:Java开发环境的熟悉
    实验楼第四次试验报告
    实验楼第三次试验报告
    实验楼第二次试验报告
    实验楼第一次试验报告
    c++程序设计中的函数重载
    C++中,new/delete和malloc/free的区别
    继承和多态二:虚析构函数
  • 原文地址:https://www.cnblogs.com/--560/p/4554438.html
Copyright © 2011-2022 走看看