完美匹配(matching)

这篇博客探讨了如何求解无向图的完美匹配数量,特别是在图中没有自环或重边的情况下。它提供了输入输出的描述,并给出了一种解决方案,即当节点数为偶数时,通过状态压缩和哈希记忆化来找到匹配的方案数。对于奇数个节点的情况,匹配数量为0。博客还包含了样例输入和输出,以及数据范围和来源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

完美匹配(matching)

题目描述

 

给定nn个点,mm条边的无向图G=(V,E)G=(V,E),求出它的完美匹配数量对106+3106+3取模的值。

一个完美匹配可以用一个排列ϕ:V→Vϕ:V→V来表示,满足(v,ϕ(v))∈E(v,ϕ(v))∈E和ϕ(ϕ(v))=vϕ(ϕ(v))=v。

 

输入

 

输入第一行,包含两个整数n,mn,m,表示图GG的点数和边数。

接下来mm行,第i+1i+1行包含两个正整数ui,viui,vi,描述第ii条无向边。ui,viui,vi为该边两个端点的标号。

保证图中没有自环或重边。

 

输出

 

 

输出一个整数,表示图GG的完美匹配数量对106+3106+3取模的值。

 

 

样例输入

样例输入1
4 4
1 3
1 4
2 3
2 4

样例输出

样例输出1
2

提示

 

样例2,3

样例解释1

排列(3,4,1,2)(3,4,1,2)和(4,3,2,1)(4,3,2,1)满足条件。

数据范围

 

来源

南外NOIP2017模拟


solution

这题问你匹配的方案数

如果n是奇数,那么就是0

偶数的话,考虑状压

令f[S]表示当前匹配的点状态为S

每次挑出两个0来匹配

用哈希存状态,记忆化一下

效率O(可以过)

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 33
#define mod 1000003
#define p 1000007
using namespace std;
int n,m,head[p],t1,t2,tot=1;
int ma[maxn][maxn];
struct node{
    int v,nex,w;
}e[p*3];
void lj(int t1,int t2,int t3){
    tot++;e[tot].v=t2;e[tot].w=t3;e[tot].nex=head[t1];head[t1]=tot;
}
int f(int S,int T){
    for(int i=head[T];i;i=e[i].nex){
        if(e[i].v==S)return e[i].w;
    }
    return -1;
}
int ask(int S){
     
    if(!S)return 1;
    if(f(S,S%p+1)!=-1)return f(S,S%p+1);
    int fi=0,sum=0;
    for(;!(S&(1<<fi));fi++);
    for(int i=fi+1;i<=n;i++){
        if((S&(1<<i-1))&&ma[fi+1][i])sum+=ask(S^(1<<fi)^(1<<i-1));
        sum%=mod;
    }
    lj(S%p+1,S,sum);
    return sum;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        scanf("%d%d",&t1,&t2);
        ma[t1][t2]=ma[t2][t1]=1;
    }
    printf("%d\n",ask((1<<n)-1));
    return 0;
}

 

### 最小权完美匹配的概念 最小权完美匹配是指在一个带权重的完全二部图中找到一种完美匹配,使得所选边的总权重之和达到最小。对于一个给定的二部图 \( G=(V,E) \),其中每条边都有一个关联的非负实数值作为其成本或距离,在此情况下寻找一条路径覆盖所有的顶点而使总的花费最少即是最小费用流问题的一种特殊情况。 在实际应用场景里,这个问题可以被描述成指派问题的形式:假设有若干项工作需要分配给相同数量的人去完成,并且每个人做不同工作的效率(时间、金钱等)各不相同,则通过构建相应的加权二分图并计算最小权完美匹配来决定最佳的任务安排方案[^1]。 为了实现这一目标,通常会采用改进版的KM算法(Kuhn-Munkres Algorithm,也称为Hungarian algorithm的一个变种),该方法能够在多项式时间内解决此类优化难题。当处理具有特殊结构的数据集时,还可以利用其他更高效的解决方案来进行加速运算。 ```python from scipy.optimize import linear_sum_assignment import numpy as np # 创建一个随机的成本矩阵表示两组节点之间的连接代价 cost_matrix = np.array([[4, 2, 5], [3, 8, 6], [9, 7, 1]]) row_ind, col_ind = linear_sum_assignment(cost_matrix) min_weight_perfect_matching_cost = cost_matrix[row_ind, col_ind].sum() print(f"The minimum weight perfect matching has a total cost of {min_weight_perfect_matching_cost}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值