首页 > 编程语言 >KM算法模板

KM算法模板

时间:2022-12-10 18:44:17浏览次数:60  
标签:pii vis1 int KM 算法 bool ans using 模板

P3967 [TJOI2014]匹配
时间复杂度是n3

#include <bits/stdc++.h>
using namespace std;
using pii=pair<int,int>;
#define fi first
#define se second
const int M=105;

int n;
int w[M][M];
int match[M],slack[M];
int lx[M],ly[M];
bool vis1[M],vis2[M];
int ans;
pii a[M];

bool dfs(int now) {
    vis1[now]=1;
    for(int i=1;i<=n;i++) {
        int cnt=lx[now]+ly[i]-w[now][i];
        if(cnt==0&&vis2[i]==0) {
            vis2[i]=1;
            if(match[i]==0||dfs(match[i])) {
                match[i]=now;
                return 1;
            }
        }
        else slack[i]=min(slack[i],cnt);
    }
    return 0;
}

void update() {
    int a=0x3f3f3f3f;
    for(int i=1; i<=n; i++) {
        if(!vis2[i])
            a=min(a,slack[i]);
    }
    for(int i=1; i<=n; i++) {
        if(vis1[i])lx[i]-=a;
        if(vis2[i])ly[i]+=a;
    }
 
}

int km() {
    memset(lx,0,sizeof(lx));
    memset(ly,0,sizeof(ly));
    memset(match,0,sizeof(match));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            lx[i]=max(lx[i],w[i][j]);
    //for(int i=1;i<=n;i++)cout<<lx[i]<<' ';cout<<endl;
    for(int i=1;i<=n;i++) {
        memset(slack,0x3f,sizeof(slack));
        while(1) {
            memset(vis1,0,sizeof(vis1));
            memset(vis2,0,sizeof(vis2));
            if(dfs(i))break;
            update();
        }
    }
    int sum=0;
    for(int i=1;i<=n;i++)
        if(match[i])sum+=w[match[i]][i];
    return sum;
}

bool check(int x,int y) {
    int tmp=w[x][y];
    w[x][y]=-1e8;
    int sum=km();
    w[x][y]=tmp;
    return sum!=ans;
}

int main() {
    cin>>n;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
        cin>>w[i][j];
    ans=km();
    cout<<ans<<endl;
    for(int i=1;i<=n;i++)
        a[i]={match[i],i};
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
        if(check(a[i].fi,a[i].se))cout<<a[i].fi<<' '<<a[i].se<<'\n';
    return 0;
}

标签:pii,vis1,int,KM,算法,bool,ans,using,模板
From: https://www.cnblogs.com/basicecho/p/16972071.html

相关文章

  • Dijkstra 算法说明与实现
    Dijkstra算法说明与实现作者:Grey原文地址:博客园:Dijkstra算法说明与实现CSDN:Dijkstra算法说明与实现问题描述问题:给定出发点,出发点到所有点的距离之和最小是多少?......
  • [2022-12-06]神经网络与深度学习hw11 - 各种优化算法比较
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • 地下城地图图块生成算法
    一.概述生成地下城,包含房间和迷宫通路。类似:示例效果一示例效果二二.思路1.生成迷宫通路从房间的边缘坐标XY为奇数的格子生成迷宫,确保房间和迷宫通路之间有......
  • openssl国密算法库
    openssl国密算法库一、开发背景openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘......
  • 算法图解笔记
    编写递归函数时,必须告诉它何时停止,因此,每个递归函数有两个部分:基线条件(basecase)和递归条件(recursivecase)。递归条件指的是函数调用自己,而基线条件则指的是......
  • oracle 客户端连接VBA模板使用教程
    首先解释一个VBA是什么。VBA全称:VisualBasicforApplications。我这里的是指办公软件excel中的VBA宏功能。Oracle中我们是可以多个客户端访问服务器端的。......
  • 每日算法之最小的K个数
    JZ40最小的K个数描述给定一个长度为n的可能有重复值的数组,找出其中不去重的最小的k个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺......
  • 贪心算法_划分字母区间
    '字符串S由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。'示例:'输入:s="abab......
  • C/C++《程序设计与算法综合实践》备选题目
    C/C++《程序设计与算法综合实践》备选题目《程序设计与算法综合实践》期末大作业题目及评分标准有如下情况之一者,为不及格。(1)未能完成所选题目评分标准的最低要求。(2)......
  • 算法导入
    一、算法分类:服务算法任务算法二、获取方法:http://docs.scu.baidu-int.com/scu-group/CVS/%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97/%E8%A7%86%E8%A7%89V2.8/%E5%9F......