zoukankan      html  css  js  c++  java
  • 二分图最佳匹配KM算法 /// 牛客暑期第五场E

    题目大意:

    给定n,有n间宿舍 每间4人

    接下来n行 是第一年学校规定的宿舍安排

    接下来n行 是第二年学生的宿舍安排意愿

    求满足学生意愿的最少交换次数

    input

    2

    1 2 3 4

    5 6 7 8

    4 6 7 8

    1 2 3 5

    output

    2

    题解

    #include <bits/stdc++.h>
    #define MAXN 205
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,mint;
    int G1[MAXN][5],G2[MAXN][5];
    int G[MAXN][MAXN],link[MAXN];
    int x[MAXN],y[MAXN];
    int visx[MAXN],visy[MAXN];
    bool DFS(int s) {
        visx[s]=1;
        for(int i=1;i<=n;i++) {
            if(visy[i]) continue;
            int tmp=x[s]+y[i]-G[s][i];
            if(tmp==0) {
                visy[i]=1;
                if(link[i]==-1 || DFS(link[i])) {
                    link[i]=s; return true;
                }
            }
            else if(tmp > 0) {
                mint=min(mint,tmp);
            }
        }
        return false;
    }
    void KM()
    {
        for(int i=1;i<=n;i++) {
            link[i]=-1; y[i]=x[i]=0;
            for(int j=1;j<=n;j++)
                x[i]=max(x[i],G[i][j]);
        }
        for(int i=1;i<=n;i++) {
            while(1) {
                mint =INF;
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                if(DFS(i)) break;
                for(int i=1;i<=n;i++) {
                    if(visx[i]) x[i]-=mint;
                    if(visy[i]) y[i]+=mint;
                }
            }
        }
        int out=0;
        for(int i=1;i<=n;i++) out+=G[link[i]][i];
        printf("%d
    ",4*n-out);
    }
    int main()
    {
        while(~scanf("%d",&n)) {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=4;j++) scanf("%d",&G1[i][j]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=4;j++) scanf("%d",&G2[i][j]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++) {
                    int cnt=0;
                    for(int p=1;p<=4;p++)
                        for(int q=1;q<=4;q++)
                            if(G1[i][p]==G2[j][q]) cnt++;
                    G[i][j]=cnt;
                }
            KM();
        }
    
    
        return 0;
    }
    View Code

    KM算法讲解

    https://blog.csdn.net/sixdaycoder/article/details/47720471

    https://blog.csdn.net/c20180630/article/details/71080521

    int n,mint;
    int G[MAXN][MAXN],link[MAXN];
    int x[MAXN],y[MAXN];
    int visx[MAXN],visy[MAXN];
    bool DFS(int s) {
        visx[s]=1;
        for(int i=1;i<=n;i++) {
            if(visy[i]) continue;
            int tmp=x[s]+y[i]-G[s][i];
            if(tmp==0) {
                visy[i]=1;
                if(link[i]==-1 || DFS(link[i])) {
                    link[i]=s; return true;
                }
            }
            else if(tmp > 0) {
                mint=min(mint,tmp);
            }
        }
        return false;
    }
    void KM()
    {
        for(int i=1;i<=n;i++) link[i]=-1; 
        for(int i=1;i<=n;i++) {
            while(1) {
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                if(DFS(i)) break;
                for(int i=1;i<=n;i++) {
                    if(visx[i]) x[i]-=mint;
                    if(visy[i]) y[i]+=mint;
                }
            }
        }
    }
    模板
  • 相关阅读:
    将博客搬至CSDN
    smarty不渲染html页面
    开篇
    html的入门——从标签开始(1)
    java内部编码
    用base64Encoder进行编码 和base64Decoder解码
    序列化和反序列化
    HttpServletResponse类
    配置Tomcat服务器数据连接池
    SVN修改地址
  • 原文地址:https://www.cnblogs.com/zquzjx/p/9420901.html
Copyright © 2011-2022 走看看