二分图最大匹配 & 最大独立集

二分图(二部图)

最大匹配 即 连接上下部分 边数和最大 的数量!

#include <iostream> 
#include <string.h> 
using namespace std; 
int n,k;  //n矩阵规格,k星体数量 
int V1,V2;          //二分图顶点集 
 /*矩阵的行列分别属于二分图的两个顶点集V1、V2,其中行x∈V1,列y∈V2*/ 
bool grid[501][501];  //存储数据方式:可达矩阵 
bool vis[501];       //记录V2的点每个点是否已被搜索过 
int link[501];        //记录 V2中的点y 在 V1中 所匹配的点x的编号 
int m;  //最大匹配数 
bool dfs(int x) 
{ 
 for(int y=1;y<=V2;y++) 
    if(grid[x][y] && !vis[y])  //x到y相邻(有边) 且 节点y未被搜索 
  { 
      vis[y]=true;      //标记节点y已被搜索 
      if(link[y]==0 || dfs(link[y])) //link[y]==0 : 如果y不属于前一个匹配M 
      {              //find(link[y] : 如果被y匹配到的节点可以寻找到增广路 
        link[y]=x;   //那么可以更新匹配M'(用M替代M') 
    return true;  //返回匹配成功的标志 
   } 
  } 
  return false;  //继续查找V1下一个x的邻接节点 
} 
 
void search(void) 
{ 
 for(int x=1;x<=V1;x++) 
 { 
  memset(vis,false,sizeof(vis)); //清空上次搜索时的标记 
    if(dfs(x))  //从V1中的节点x开始寻找增广路 
   m++; 
 } 
 return; 
}

二分图最大匹配 hdu2063

//15MS	1248K	989 B
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 510
int g[MAX][MAX];
int K,M,N;
bool vis[MAX];
int link[MAX];
int m;
bool dfs(int src)
{
    for(int i=1;i<=N;i++)
    {
        if(g[src][i]&&!vis[i])
        {
            vis[i]=true;
            if(link[i]==0||dfs(link[i]))
            {
                link[i]=src;
                return true;
            }
        }
    }
    return false;
}
void search()
{
    memset(link,0,sizeof(link));
    for(int i=1;i<=M;i++)
    {
        memset(vis,false,sizeof(vis));
        if(dfs(i)) m++;
    }
}
int main()
{
    while(1)
    {
        scanf("%d",&K);
        if(!K) break;
        scanf("%d%d",&M,&N);
        m=0;
        memset(g,0,sizeof(g));
        for(int i=1;i<=K;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x][y]=1;
        }
        search();
        printf("%d\n",m);
    }
    return 0;
}


最大独立集

=总权-最大匹配数

//448K	954MS	C++	1807B
#include <iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define clr(x) memset(x,0,sizeof(x))
int T;
int N;
int m;
struct People
{
    int heigh;
    char sex[5];
    char music[105];
    char sports[105];
}p[510];
struct Node
{
    int point;
    int next;
}node[200005];
int tot;
int head[510];
int vis[510];
int link[510];
bool cheak(People p1,People p2)
{
    if(abs(p1.heigh-p2.heigh)>40)
        return false;
    if(strcmp(p1.music,p2.music))
        return false;
    if(strcmp(p1.sports,p2.sports)==0)
        return false;
    return true;
}
void add(int x,int y) /*****邻接表*****/
{
    tot++;
    node[tot].next=head[x];
    node[tot].point=y;
    head[x]=tot;
}
bool dfs(int src)
{
    for(int e=head[src];e!=0;e=node[e].next)
    {
        if(!vis[node[e].point])
        {
            vis[node[e].point]=1;
            if(link[node[e].point]==0||dfs(link[node[e].point]))
            {
                link[node[e].point]=src;
                return true;
            }

        }
    }
    return false;
}
void search()
{
    for(int i=1;i<=N;i++)
    {
        clr(vis);
        if(p[i].sex[0]=='F'&&dfs(i))
            m++;
    }
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        /*********初始化*********/
        m=0;
        tot=0;
        //clr(node);
        clr(head);
        clr(link);

        scanf("%d",&N);
        for(int i=1;i<=N;i++)
        {
            scanf("%d%s%s%s",&p[i].heigh,p[i].sex,p[i].music,p[i].sports);
        }
        /******能做夫妻的就加为边******/
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
            if(p[i].sex[0]=='F'&&p[j].sex[0]=='M'&&cheak(p[i],p[j]))
            add(i,j);
            /**********求能做夫妻的最大匹配*************/
            search();
            /*********最大独立集=总权-最大匹配************/
            printf("%d\n",N-m);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 二分最大权重匹配是指在一个二分中,找出一种最佳的方式将中的顶点分成两个独立的集合,并使得两个集合中的顶点之间的边权重之和最大。 对于在Matlab中进行二分最大权重匹配的仿真,可以使用匈牙利算法(Hungarian algorithm)来实现。匈牙利算法是一种经典的解决二分最大权重匹配问题的算法,其基本思想是从一个点开始,通过不断更新和选择边,直到找到一种匹配方式使得边权重之和最大。 具体实现步骤如下: 1. 构建二分的邻接矩阵:根据你的实际问题,首先需要将二分中的顶点和边转化为一个邻接矩阵。邻接矩阵是一个矩阵,其中的元素表示两个顶点之间是否有边相连,如果相连则为1,否则为0。 2. 初始化匹配信息:创建一个大小为二分顶点数目的数组,用来记录每个顶点所匹配的另一个顶点。初始时,所有顶点都未匹配,可以将数组的所有值设为-1。 3. 循环匹配过程:从一个未匹配的顶点出发,使用深度优先搜索(DFS)找到一条增广路径。增广路径是指一条从一个未匹配的顶点出发,经过若干条已匹配和未匹配的边,再回到另一个未匹配顶点。 4. 调整匹配:在找到增广路径后,需要根据是否存在交替路径来决定是否需要调整当前的匹配。交替路径是指一条从一个未匹配的顶点出发,经过已匹配边和未匹配边,再回到另一个未匹配顶点的路径。如果存在交替路径,则交换路径上已匹配和未匹配的边,直到找不到更多的增广路径。 5. 返回结果:重复执行步骤3和步骤4,直到不能找到增广路径为止。最后,所有匹配的顶点对就是二分最大权重匹配的结果。 以上就是使用Matlab进行二分最大权重匹配的大致流程。根据具体的问题和二分的规模,你可能需要适当调整和优化算法以提高运行效率。 ### 回答2: 二分最大权重匹配是指在一个由两个不相交集合构成的二分中,寻找一种匹配方式,使得匹配边的权重之和最大。 在MATLAB中,可以使用论工具箱中的函数来实现二分最大权重匹配的仿真。具体步骤如下: 1. 构建二分:首先根据问题的实际情况,将两个集合分别用两个数组表示,并将它们分别作为参数传入`biograph`函数中,构建二分对象。 2. 设置边权重:使用`addedge`函数为每条边设置权重。可以根据实际情况设置不同边的权重,例如可以将边的权重表示为两个集合之间的相关性或者重要性。 3. 求解最大权重匹配:使用`maxflow`函数来求解最大权重匹配。将二分对象作为参数传入函数中,该函数会返回一个最大权重匹配的结果。 4. 分析结果:根据返回的结果,可以分析每个节点的匹配情况,以及匹配边的权重之和。可以通过遍历节点和边的方式,获取每个节点的匹配对象以及对应的权重。 5. 可视化结果:使用画函数例如`plot`,可以将匹配结果可视化展示。 总之,MATLAB提供了论工具箱,可以方便地进行二分最大权重匹配的仿真实验。通过构建二分、设置边权重、求解最大权重匹配、分析结果和可视化结果等步骤,可以得到二分最大权重匹配的仿真结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值