二分图 匈牙利算法应用

二分图---染色法(判断二分图),匈牙利算法(二分图的最大匹配) //概念,应用场景,判定证明,算法思路,示例 二分图是图论中的一个重要概念,指的是一个图的顶点集可以被分为两个互不相交的子集,并且图中的每条边都连接两个不同子集中的顶点。:在网络流问题中,二分图可以表示一种特殊的流网络,其中顶点集分为源点集和汇点集,边表示从源点到汇点的流量路径,用于建模输送网络中的流量分配和优化问题。:在二分图中,匹配问题是指找到一种边的子集,使得图中每个顶点都与子集中的某条边相邻。二分图的匹配:给定一个二分图 G,在 G 的一个子图 M 中,M 的边集 {E} 中的任意两条边都不依附于同一个顶点,则称 M 是一个匹配。 阅读详情

匈牙利算法是kuangbin的

poj 1274 poj 2239 //水题

poj 2584

这个还是有点想法的,把每种衣服拆成n件衣服(每件衣服都是一个单独的节点),然后依次连接


下面是代码,思路还是比较清晰的


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;


/* **************************************************************************
//二分图匹配(匈牙利算法的DFS实现)
//初始化:g[][]两边顶点的划分情况
//建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配
//g没有边相连则初始化为0
//uN是匹配左边的顶点数,vN是匹配右边的顶点数
//调用:res=hungary();输出最大匹配数
//优点:适用于稠密图,DFS找增广路,实现简洁易于理解
//时间复杂度:O(VE)
//***************************************************************************/
//顶点编号从0开始的
const int MAXN=400;
int uN,vN;//u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
bool dfs(int u)//从左边开始找增广路径
{
    int v;
    for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
      if(g[u][v]&&!used[v])
      {
          used[v]=true;
          if(linker[v]==-1||dfs(linker[v]))
          {//找增广路,反向
              linker[v]=u;
              return true;
          }
      }
    return false;//这个不要忘了,经常忘记这句
}
int hungary()//xiongyali
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u)) res++;
    }
    return res;
}
//******************************************************************************/

int F[100],A[100],tmp[50];
int judge(char t){
    if(t=='S')return 1;
    else if(t=='M')return 2;
    else if(t=='L')return 3;
    else if(t=='X')return 4;
    else return 5;

}
int main()
{
     int v;
     int k,k1,k2;
     char str[30];
     while(~scanf("%s",&str)&&strcmp(str,"ENDOFINPUT")!=0)
     {
         scanf("%d",&uN);
         memset(g,0,sizeof(g));
         getchar();
         for(int i=0;i<uN;i++)
         {
             char t1,t2;
             scanf("%c%c",&t1,&t2);
             getchar();
             F[i]=judge(t1);
             A[i]=judge(t2);

         }
         memset(tmp,0,sizeof(tmp));
         for(int i=1;i<=5;i++){
            scanf("%d",&tmp[i]);
            tmp[i]+=tmp[i-1];
         }
         for(int i=0;i<uN;i++){
            for(int j=F[i];j<=A[i];j++){
                for(int k=tmp[j-1]+1;k<=tmp[j];k++)g[i][k]=1;
            }
         }
         vN=tmp[5]+20;//刚开始这里写的是6*12+11,WA,后来又+5,莫名其妙AC了,我也不知道为什么......
         int re=hungary();
         getchar();
         scanf("%s",&str);
         getchar();
         if(re==uN)printf("T-shirts rock!\n");
         else printf("I'd rather not wear a shirt anyway...\n");

     }
     return 0;
}

poj 2536

这题是水题,可是老是A不了,我也不知道为什么,我的思路和代码风格完全和题解并没有太大区别

poj 2446

这题我是这样写的

然后老是WA怎么也改不过来......

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;


/* **************************************************************************
//二分图匹配(匈牙利算法的DFS实现)
//初始化:g[][]两边顶点的划分情况
//建立g[i][j]表示i->j的有向边就可以了,是左边向右边的匹配
//g没有边相连则初始化为0
//uN是匹配左边的顶点数,vN是匹配右边的顶点数
//调用:res=hungary();输出最大匹配数
//优点:适用于稠密图,DFS找增广路,实现简洁易于理解
//时间复杂度:O(VE)
//***************************************************************************/
//顶点编号从0开始的
const int MAXN=1500+50;
int uN,vN;//u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
int maze[500][500];
bool dfs(int u)//从左边开始找增广路径
{
    int v;
    for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
      if(g[u][v]&&!used[v])
      {
          used[v]=true;
          if(linker[v]==-1||dfs(linker[v]))
          {//找增广路,反向
              linker[v]=u;
              return true;
          }
      }
    return false;//这个不要忘了,经常忘记这句
}
int hungary()//xiongyali
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))res++;
    }
    return res;
}
//******************************************************************************/
int n,m;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool ok(int x,int y){
    if(x<=0||x>n||y<=0||y>m||maze[x][y]==-1)return false;
    return true;
}
void deal(){
    uN=n*m+5;
    vN=n*m+5;
    memset(g,0,sizeof(g));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int k=0;k<4;k++){
                int x=i+dir[k][0],y=j+dir[k][1];
                if(ok(x,y))g[(i-1)*m+j-1][(x-1)*m+y-1]=1;
            }
        }
    }

}


int main()
{
    int k,x,y;
     while(~scanf("%d%d%d",&n,&m,&k)){
         memset(maze,0,sizeof(maze));

        for(int i=1;i<=k;i++){
            scanf("%d%d",&y,&x);
            maze[x][y]=-1;
        }
        deal();
        int re=hungary();
        if((n*m-k)%2)printf("NO\n");
        else if(re+k==n*m)printf("YES\n");
        else printf("NO\n");
     }
}

然后我就看了看kuangbin的思路,没办法,改的和他一样过了......

其实我也不知道我之前的思路到低哪里不对了,现在也不知道

以下是正确代码

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=2500+50;
int uN,vN;//u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
int maze[500][500],num[50][50];
bool dfs(int u)//从左边开始找增广路径
{
    int v;
    for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
      if(g[u][v]&&!used[v])
      {
          used[v]=true;
          if(linker[v]==-1||dfs(linker[v]))
          {//找增广路,反向
              linker[v]=u;
              return true;
          }
      }
    return false;//这个不要忘了,经常忘记这句
}
int hungary()//xiongyali
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))res++;
    }
    return res;
}
//******************************************************************************/
int n,m;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool ok(int x,int y){
    if(x<=0||x>n||y<=0||y>m||maze[x][y]==-1)return false;
    return true;
}



int main()
{
     int k,x,y;
     while(~scanf("%d%d%d",&n,&m,&k)){
         memset(maze,0,sizeof(maze));
         memset(num,0,sizeof(num));
         memset(g,0,sizeof(g));
        for(int i=1;i<=k;i++){
            scanf("%d%d",&y,&x);
            maze[x][y]=-1;
        }
        int tol=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(maze[i][j]!=-1)num[i][j]=tol++;
            }
        }
        uN=vN=tol;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(maze[i][j]!=-1)
                {
                  int u=num[i][j];
                  if(i-1>0&&maze[i-1][j]!=-1)g[u][num[i-1][j]]=1;
                  if(j-1>0&&maze[i][j-1]!=-1)g[u][num[i][j-1]]=1;
                  if(i+1<=n&&maze[i+1][j]!=-1)g[u][num[i+1][j]]=1;
                  if(j+1<=m&&maze[i][j+1]!=-1)g[u][num[i][j+1]]=1;
                }




        int re=hungary();
        if((n*m-k)%2)printf("NO\n");
        else if(re==tol)printf("YES\n");
        else printf("NO\n");
     }
}

poj 3041

这个题我要好好写写题解(其实是看别人的)我自己想了想,感觉和二分图实在是扯不上关系......

这是别人的说法

这个题目属于标准的图论题目,需要适当的转换,建立适当的图来进行结题。建立二分图,设置x坐标作为A点集,y坐标作为B点集。那么每个点转化成连接A、B点集的边。问题就转化成最小点覆盖问题,即若选定一个点,那么于此点相连的所有边都被选定,求满足选定所有边的最少的点集。最小点覆盖问题可以用二分图的最大匹配来解。最小点数=最大匹配数(此处不在证明,详情请看上篇文章)。这样通过构建二分图求解最大匹配数,来求解该问题的最小点覆盖。

然后这题就是大水题了......


这个题之前见过,总想着是不是个贪心,前人经验证明贪心不可做

以下是代码

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=2500+50;
int uN,vN;//u,v数目
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
int maze[500][500],num[50][50];
bool dfs(int u)//从左边开始找增广路径
{
    int v;
    for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改
      if(g[u][v]&&!used[v])
      {
          used[v]=true;
          if(linker[v]==-1||dfs(linker[v]))
          {//找增广路,反向
              linker[v]=u;
              return true;
          }
      }
    return false;//这个不要忘了,经常忘记这句
}
int hungary()//xiongyali
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0;u<uN;u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))res++;
    }
    return res;
}
//******************************************************************************/
int n,m;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool ok(int x,int y){
    if(x<=0||x>n||y<=0||y>m||maze[x][y]==-1)return false;
    return true;
}



int main()
{
    int n,k,x,y;
     while(~scanf("%d%d",&n,&k)){
            memset(g,0,sizeof(g));
            uN=n+1,vN=n+1;
        while(k--){
            scanf("%d%d",&x,&y);
            g[x--][y--]=1;
        }
     printf("%d\n",hungary());
     }
}

poj 1325

这题不难,不过有个地方需要注意

就是初始状态两个机器都是状态0,所以有个事要注意,就是所有和0相连的的边都要删掉......(就因为这个WA了几次)


poj 2226

这个题挺难想的

我是看别人的题解看出来的

以下是别人的分析

题意:R*C的矩阵表示一块田地,'*'表示湿地,'.'表示草地。现在FJ要在田地上铺木板盖掉所有的湿地,露出所有的草地。每块木板的宽度为1,长度为任意长。问FJ最少用几块木板就可以完成任务?

思路:看了半天,实在是没思路,看了看别人的报告才明白。把它转化为一个二分图,求最小点覆盖。
但如何构成二分图呢??
就是把每一行中不相连的一块区域看成一个点,同理每一列也一样。然后就有点像3041那题一样。求它的最小点覆盖

*.*.   按行1  0  2  0    按列 1  0  4  0

.***           0  3  3  3             0  3  4  5

***.           4  4  4  0             2  3  4  0

..*.            0   0  5  0            0  0  4  0

下面是代码

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int n,m,cnt1,cnt2,map[2520][2520],linker[2520],vis[2520];
int g1[60][60],g2[60][60],tg[60][60];
char str[60][60];

int DFS(int u){
    int v;
    for(v=1;v<=cnt2;v++)
        if(map[u][v] && !vis[v]){
            vis[v]=1;
            if(linker[v]==-1 || DFS(linker[v])){
                linker[v]=u;
                return 1;
            }
        }
    return 0;
}

int Hungary(){
    int u,ans=0;
    memset(linker,-1,sizeof(linker));
    for(u=1;u<=cnt1;u++){
        memset(vis,0,sizeof(vis));
        if(DFS(u))
            ans++;
    }
    return ans;
}

int main(){

    //freopen("input.txt","r",stdin);

    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i<n;i++)
            scanf("%s",str[i]);
        memset(g1,0,sizeof(g1));
        memset(g2,0,sizeof(g2));
        cnt1=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++){
                if(str[i][j]=='*'){
                    if(j==0)
                        g1[i][j]=++cnt1;
                    else if(str[i][j-1]=='*')
                        g1[i][j]=g1[i][j-1];
                    else
                        g1[i][j]=++cnt1;
                }
            }
        cnt2=0;
        for(int j=0;j<m;j++)    //注意这里
            for(int i=0;i<n;i++){
                if(str[i][j]=='*'){
                    if(i==0)
                        g2[i][j]=++cnt2;
                    else if(str[i-1][j]=='*')
                        g2[i][j]=g2[i-1][j];
                    else
                        g2[i][j]=++cnt2;
                }
            }
        memset(map,0,sizeof(map));
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(str[i][j]=='*')
                    map[g1[i][j]][g2[i][j]]=1;
        int ans=Hungary();
        printf("%d\n",ans);
    }
    return 0;
}
但是其实精髓还是不由完全掌握,以后遇见还要注意......



匈牙利算法:二分图最大匹配的原理、实现与应用场景详解 图论中的匹配问题旨在寻找图中互不相邻的边集,是组合优化与资源分配领域的核心基础。其经典模型二分图匹配,将顶点划分为两个独立集合,要求匹配边仅连接不同集合的顶点,这自然对应着任务调度、人员分配等实际场景。匈牙利算法是解决二分图最大匹配问题的经典方法,其核心原理是通过深度优先搜索不断寻找增广路径并取反,从而逐步增加匹配数,直至无法找到为止。该算法思想简洁高效,时间复杂度为O(VE),不仅是理解网络流中增广路思想的重要前置,更是学习带权匹配KM算法的基础。在工程实践中,匈牙利算法广泛应用于任务分配、棋盘覆盖、学生 阅读详情

相关推荐

二分图核心算法与应用:从染色法、匈牙利算法到工程实践

图论中的匹配与覆盖问题是算法与工程领域的常见挑战,其核心在于对关系的高效建模与优化。二分图作为一种特殊图结构,能将复杂的两类实体间关系抽象为清晰的计算模型,其核心性质是图中不含奇数长度的环。基于这一原理,染色法成为判定二分图的有效手段。在工程实践中,二分图的最大匹配问题具有重要技术价值,它广泛应用于任务调度、资源分配、广告投放等场景,旨在实现最优的配对方案。匈牙利算法以其“先到先得,能让则让”的朴素思想,成为解决该问题的经典方法。对于大规模数据,Hopcroft-Karp算法通过BFS分层与DFS多路增广进

weixin_34357436的博客 354

【二分图算法】手把手教你学会:染色法(判断二分图)、匈牙利算法(二分图的最大匹配)

就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。(不一定是连通图)💡匹配(本质是一个边的集合!给定一个二分图S,在S的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。💡极大匹配极大匹配是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。(也就是说,再加入任意一条不在匹配集合中的边,该边肯定有一个顶点已经在集合中的边中了)💡最大匹配。

Yaoyao2024的博客 4546

二部图和匈牙利算法

设G为二分图,若在G的子图M中,任意两条边都没有公共节点,那么称M为二分图G的一组匹配。在二分图中,包含边数最多的一组匹配称为二分图的最大匹配。交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。增广路:从一个未匹配点出发,走交替路,若能到达另一个未匹配点,则这条交替路称为增广路。例如,3一5→1→4→2—7观察增广路,我们会发现:非匹配边比匹配边多一条。只要把增广路中的匹配边和非匹配边的身份交换(即倒过来走),交换后,图中的匹配边数目比原来多了1条。

qq_52053775的博客 948

二分图的最大匹配、完美匹配和匈牙利算法

这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm);不讲带权二分图的最佳匹配。 1. 二分图的基本知识点 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交集 $U$ 和$V$ ,使得每一条边都分别连接$U$、$V$中的顶点。如果存在

开源节流 2万+

二分图算法及其应用:从匹配问题到匈牙利算法实战

二分图是图论中的一种特殊图,它广泛应用于网络流、优化问题等领域。本章将从二分图的基本概念、性质和判定方法等角度进行详细解读。匈牙利算法(Hungarian algorithm),由Harold Kuhn和James Munkres提出,是一类在图论中寻找二分图最大匹配的有效算法。该算法广泛应用于各种分配问题,如婚姻问题、工作分配问题等,它为解决这类问题提供了一种有效的数学模型和解决方案。构建初始匹配是匈牙利算法的第一步。这通常涉及到寻找一个完美匹配,或是找到一个尽量大的匹配。

weixin_32747681的博客 1432

用户存续期价值评估CLV(二) BG/NBD Model python模拟

BG/NBD Model …继续 想象每一个客户有两个硬币,一个“Buy Coin"控制客户购买的概率;一个"Die Coin"控制客户流失、不再购买的概率。 前面假设了客户的交易次数服从泊松过程: 在一年中的每个月,客户都以抛硬币的方式来决定是否购买。我们所观察到的购买次数取决与泊松分布的参数 ????。 %matplotlib inline import numpy as np impor...

weixin_43171270的博客 3426

图解二分图 --- 染色法、匈牙利算法

4、至少有两个邻接点染色相同,则染色失败,(邻接点染相同颜色的话,说明这两个点在同一集合,而二分图是不能有邻接点在同一集合的)不是二分图,否则就是二分图。1、我们这里将1和2代表两种颜色(也就是两个集合,染1的在一个集合,染2的在另一个集合),初始时所有点颜色都为0,代表未染色。二分图所有的点可以分为两个集合V1、V2,图中任意一条边的两个顶点分别在不同的集合,即任意一个集合的内部不能有边。二分图就是可以把所有点划分到两边集合中去,使得所有的边在两个集合外且在两个集合之间,集合内部没有边的图。......

weixin_60569662的博客 800

Drools vs URule:5个真实项目场景告诉你如何选择开源规则引擎

本文通过电商风控、物流计费、会员体系、保险定价和物联网告警五个真实项目场景,深度对比了Drools与URule两款开源规则引擎。分析了两者在规则复杂度、性能表现、开发运维及适用场景上的核心差异,为技术选型提供基于实战的决策指南。

k6l7m8n9的博客 944

二分图匹配及匈牙利算法的全面讲解及python实现

1、背景 在生活中常常遇到两组元素多对多匹配而又数目有限的情况,我们需要对其进行最大匹配数的分配,使效率最大化。例如,有一组压缩气缸和一组压缩活塞,每一个型号的压缩气缸有一个固定的内径大小,每一个型号的压缩活塞可以匹配内径在一定范围内的气缸,使用匈牙利算法得到活塞和气缸对大匹配数的方案。 2、二分图定义 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可...

Trisyp的博客 4213

三相逆变器双pi控制器参数如何调节_光伏逆变器短路特性简析

1前言短路故障相对于其他故障类型来说是比较常见的,不同的设备的短路故障,大了讲都一样,细了说各有千秋,今天我们主要聊聊光伏逆变器的短路特征。电力系统中的电源,传统意义是指的是并入电力系统的同步发电机。但随着分布式发电技术的发展,各种形式的发电装置并入电力系统。按照分布式电源并网的方式,我们大致可以分为以下三类:➤通过旋转电机和变流器并联并网的电源,主要指双馈风力发电系统;➤仅仅通过变流器...

weixin_39901404的博客 1732

广工计组f4b 8位12指令微程序CPU设计实验报告(内含可通过代码以及波形图)

实验目的:模型机是计算机的缩细模型,通过它可以理解计算机整机的结构和功能,理解CPU,存储器,中断控制器,接口的结构及实现逻辑和各部件之前的接口关系。本实验是设计一个8位模型计算机。:一条机器指令可以分解成一个微操作序列,这些微操作是计算机最基本的,不可再细分的操作。:在微程序控制的计算机中。将控制部件向执行部件发出的各种控制命令成为微命令,它是构成控制序列的最小单位。微命令和微操作是一一对应的。微命令是微操作的控制信号,微操作微命令的执行过程。2.:微指令是若干微命令的集合。

weixin_63692154的博客 4705

数据结构与算法 - 二分图匹配:匈牙利算法的应用场景

摘要: 本文深入探讨了二分图匹配问题及其经典解法——匈牙利算法。文章首先介绍了二分图的定义与性质,阐述了匹配问题在任务分配、课程选择等实际场景中的应用。随后详细解析匈牙利算法的核心思想,重点讲解了增广路径的概念及算法步骤,并通过Python代码实现演示了基于DFS的求解过程。最后,文章分析了算法的时间复杂度(O(VE))并提供了优化建议。该算法能高效解决最大匹配问题,在资源分配等场景中具有重要价值,是图论中的基础算法之一。(149字)

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

YOLOv11改进 | Conv篇 | AKConv轻量级架构下的高效检测(附代码 + 修改方法 + 二次创新)

本文给大家带来的改进内容是AKConv是一种创新的变核卷积,它旨在解决标准卷积操作中的固有缺陷(采样形状是固定的),AKConv的核心思想在于它为卷积核提供了任意数量的参数和任意采样形状,能够使用任意数量的参数(如1, 2, 3, 4, 5, 6, 7等)来提取特征,这在标准卷积和可变形卷积中并未实现​​。AKConv能够根据硬件环境,使卷积参数的数量呈线性增减非常适用于轻量化模型的读者)。

Snu77的博客 1万+

二分图的应用(二分图匹配-匈牙利算法)

希望大家都知道哈子是二分图。二分图就是两队节点,内部互不相连,两堆节点之间有边相连。 二分图匹配 根据其性质易得图中只存在长度为偶数环,可用涂色法,把和该节点相对的节点设成不同的颜色,这样在同一堆的节点颜色相同,假如有矛盾,就不是二分图 这里是邻接表版。 int n;//节点数 vector<int> G[N];//G[i]表示i节点邻接的点,就是邻接表 int color[...

Robert_6277的博客 503

数据挖掘实战-基于KMeans算法对超市客户进行聚类分群

本实验基于KMeans算法对超市客户进行了聚类分群。通过对客户购物数据进行聚类,我们成功将客户分为不同的群体。每个群体代表了具有相似购物行为和偏好的客户群体。通过实验结果,我们发现了客户群体之间的明显差异和共性。不同群体的客户在购买频率、购物金额和购买种类等方面有所区别。这为超市提供了重要的市场细分信息,帮助超市经营者更好地了解不同客户群体的需求和喜好,制定有针对性的营销策略和商品推荐,提高客户满意度和忠诚度。此外,实验还揭示了超市客户的购物行为规律,为超市优化商品陈列和促销策略提供了指导。

m0_64336780的博客 2万+

【四足机器人项目实战】MIT四足机器人力控电机优劣分析及解决办法

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录系列文章目录前言一、mit力控电机方案二、弊端三、优点四、解决办法设计相关看专栏其他博客 前言 认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长! 本文先对XXX做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章 提示:以下是本篇文章正文内容 一、mit力控电机方案 MITCheetahMini驱动器采用的电机是类似于公版电机T-MotorU8的型号

qq_35635374的博客 6090

匈牙利算法C++实现:从二分图匹配到实战应用

图论中的匹配问题旨在寻找图中互不相连的边集,是组合优化的基础课题。其核心原理在于通过增广路径迭代改进匹配方案,直至无法优化。这一原理在工程中价值显著,能高效解决资源受限下的一对一分配需求。匈牙利算法正是实现二分图最大匹配的经典方法,它采用DFS/BFS遍历与邻接表存储,通过“协商调整”机制动态优化匹配。该算法广泛应用于任务调度、在线广告匹配、多目标跟踪等场景,例如在招聘系统中实现智能人岗匹配,或在分布式计算中分配任务与服务器。掌握其C++实现,尤其是对visited数组状态的管理和稀疏图的处理,是提升算法实

weixin_31412781的博客 252

Docker/Hyper-V/Wsl2等虚拟化组件一键切换工具 (附源码, Docker Desktop开发模式与三角洲游戏模式一键切换工具)

开启 Docker、Hyper-V 或 WSL2 后游戏无法启动?🎮💻 本文教你用一键批处理工具⚡快速切换“开发/游戏模式”,开发娱乐两不误!🔄✨

XiaoqiangClub的博客 698

“二分图匹配策略:匈牙利算法详解与应用实践“

通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(暂时不考虑特殊的性取向),如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在让我们无视掉所有的单相思,你拥有的大概就是下面这样一张关系图,每一条连线都表示互有好感。二分图的匹配:给定一个二分图 𝐺,在 𝐺 的一个子图 𝑀 中,𝑀 的边集 {𝐸} 中的任意两条边都不依附于同一个顶点,则称 𝑀 是一个匹配。输出一个整数,表示二分图的最大匹配数。

Rockivy的博客 988

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

二分图算法全解析:从匈牙利算法到KM算法与实战应用

图论中的匹配问题,旨在寻找图中互不冲突的边集,是组合优化领域的核心概念。其基本原理在于将对象抽象为顶点,关系抽象为边,通过特定算法寻找最优配对方案。这一技术具有极高的工程价值,广泛应用于任务调度、资源分配、推荐系统等需要解决“一对一”或“一对多”约束的场景。例如,在云计算中调度虚拟机到物理主机,或在相亲平台进行用户推荐,其底层模型常常可以归结为二分图匹配问题。本文聚焦于二分图这一特殊且强大的图结构,它要求顶点能划分为两个集合,且所有边只存在于集合之间。针对此类模型,匈牙利算法提供了求解最大匹配的经典思路,而

weixin_32451529的博客 726

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

匈牙利算法(Hungarian algorithm)

匈牙利算法主要用于解决一些与二分图匹配有关的问题,所以我们先来了解一下二分图。 二分图(Bipartite graph)是一类特殊的图,它可以被划分为两个部分,每个部分内的点互不相连。下图是典型的二分图。 一张二分图 可以看到,在上面的二分图中,每条边的端点都分别处于点集X和Y中。匈牙利算法主要用来解决两个问题:求二分图的最大匹配数和最小点覆盖数。 这么说起来过于抽象了,我们现在从实际问题出发。 最大匹配问题 看完上面讲的,相信读者会觉得云里雾里的:这是啥?这有啥用?所以我们把这张二分图稍微

qq_30905243的博客 2248

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

二分图最大匹配——匈牙利算法

二分图最大匹配(一)、二分图的介绍1、定义2、充要条件(二)、二分图的匹配1、二分图的最大匹配2、增广路径3、匈牙利算法(1)、复杂度 (一)、二分图的介绍 1、定义 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点 i 和 j 分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 2、充要条件 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的

hahahahahaha5的博客 1万+

匈牙利算法 寻找二分图的最大匹配数和最小点覆盖数

匈牙利算法(Hungarian algorithm)。匈牙利算法主要用于解决一些与二分图匹配有关的问题,所以我们先来了解一下二分图。 二分图(Bipartite graph)是一类特殊的图,它可以被划分为两个部分,每个部分内的点互不相连。下图是典型的二分图。 一张二分图 可以看到,在上面的二分图中,每条边的端点都分别处于点集X和Y中。匈牙利算法主要用来解决两个问题:求二分图的最大匹配数和最小点覆盖数。 这么说起来过于抽象了,我们现在从实际问题出发。 最大匹配问题 看完上面讲的,相信读者会觉得

Tequila0v0的博客 648

匈牙利算法

一、匈牙利算法(俗称“渣男算法”?) 匈牙利算法是对于一个二分图的概念上求一个最大匹配。 二、关于二分图 什么是二分图?请看这个链接:二分图 那什么是二分图的匹配和最大匹配呢? 二分图的匹配:给定一个二分图 G,在 G 的一个子图 M 中,M 的边集 {E} 中的任意两条边都不依附于同一个顶点,则称 M 是一个匹配。 二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。 下面我们看图文解释: 在这张图中,我们发现每一条边两边所依附的顶点都是不同的,并且四组都可以

c__chong的博客 6465

二分图、匈牙利算法

完全二分图是一种特殊的二分图,可以把图中的顶点分成两个集合,使得第一个集合中的所有顶点都与第二个集合中的所有顶点相连。很显然,主要的效率问题就是,在唯一的while循环里面,有1个从1到n的循环,只为了检索一些特定的目标出来。题目大意就是把图分成二分图,如果不能的话,输出-1,如果能的话,分别输出2个部分的点的数量和点的标号。二分图是指,可以把图中的顶点分成两个集合,使得每个集合中的所有点之间都是互不相连的。表面上有3层循环,实际上外面的2层while循环是有限制的,合起来也就是大约n而已。

nameofcsdn的博客 1323

二分图——棋盘覆盖(匈牙利算法的应用)

白色的是偶数格,黑色的是奇数格,可以发现,白色格子四个方向都是黑色格,黑色格子四个方向都是白色格子。满足了对于划分的两个集合中任意一个,同一个集合内没有边的要求。有了边之后就要把边的两个端点划分成两个集合,这里可以把行号和列号加起来是偶数的格子看成集合1,加起来是奇数的看成集合2。在里面,有一个任意两张骨牌都不重叠,与要素2相对应,每一个骨牌都是由两个相邻方格构成,可以将骨牌看成一条边连接了两个方格。1.节点能分成两个独立的集合,每个集合内部没有边互相连接。2.每一个节点只能与另一个集合有一条匹配边相连。

测试 734
上一篇: 网络流
下一篇: 位运算的一些巧用
is_it_a_error
博客等级 码龄11年 1粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值