hdu 5943 素数分布+二分图匹配

本文针对一个具体的区间匹配问题进行分析,提出了一种基于二分图匹配的解决方案,并详细阐述了解决过程中遇到的问题及应对策略。

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

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943


题意:两个区间,一个1-n 一个 s+1----s+n 问  s重新排列放在第一个里面,使得所有  si%(kth)==0。。。叙述不清楚大家可以看原题


思路:一眼看去不可做。。大概猜一猜如果范围小就是一个二分图匹配嘛。。。又因为素数分布确实是很近的(具体有各种各种猜想。)。。所以直接莽,

但是!!。。。重现赛时候忘记处理一种情况了。。就是区间重叠的时候。。因为之前为什么可以特判区间大就无法匹配了,因为有两个以上素数肯定没法匹配(素数只 能和1匹配。。)但是区间相交就可以和自己匹配了。。所以怎么办呢。。其实就是抹掉相交区间就可以了。。(重现赛的时候因为这个低级错误一直WA。。。一下来就 小黄鸭调试法了?)


代码:

#include <bits/stdc++.h>
using namespace std;

int n,s;
const int MAXN = 1000;
int uN,vN;//u,v的数目,使用前面必须赋值
int g[MAXN][MAXN];//邻接矩阵
int linker[MAXN];
bool used[MAXN];

bool dfs(int u){
    for(int v = 0; v < vN; v++)
        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(){
    int res = 0;
    memset(linker,-1,sizeof(linker));
    for(int u = 0; u < uN; u++){
        memset(used,false,sizeof(used));
        if(dfs(u))res++;
    }
    return res;
}
int main(){
    int t,ca=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&s);
        if(s<n)swap(n,s);
        if(n>500){
            printf("Case #%d: No\n",ca++);
        }
        else{
            memset(g,0,sizeof(g));
            for(int i=s+1;i<=s+n;i++){
                for(int j=1;j<=n;j++){
                    if(i%j==0){
                        g[j-1][i-s-1]=1;
                    }
                }
            }
            uN=n,vN=n;
            if(hungary()==n){
                 printf("Case #%d: Yes\n",ca++);
            }
            else{
                 printf("Case #%d: No\n",ca++);
            }
        }
    }
}




在解答HDU1150和HDU2255这两个二分图匹配问题时,匈牙利算法是一个非常实用的工具。为了帮助你更好地理解和应用这一算法,推荐查看《二分图匹配算法实现:匈牙利算法与KM算法》这本书籍,它详细地解释了二分图匹配以及匈牙利算法和KM算法的实现细节,并提供了实例代码,这将直接帮助你解决HDU1150和HDU2255的问题。 参考资源链接:[二分图匹配算法实现:匈牙利算法与KM算法](https://wenku.youkuaiyun.com/doc/601h4knr28?spm=1055.2569.3001.10343) 在HDU1150中,问题通常描述为在一个社团中为每对男女找到合适的配对,保证没有一对男女在同一对中多次出现。HDU2255则可能是一个更为复杂的分配问题,需要对算法进行适当的调整来满足特定的约束条件。 下面是匈牙利算法解决这类问题的基本代码框架,其中包含注释,以助于理解每个步骤的实现: ```c #include <stdio.h> #include <string.h> #define MAXN 510 #define INF 0x3f3f3f3f int n, m; int match[MAXN]; // 匹配数组,记录匹配情况 int vis[MAXN]; // 标记数组,记录节点是否被访问过 int link[MAXN]; // 链接数组,用于记录增广路径 int graph[MAXN][MAXN]; // 邻接矩阵表示图 int dfs(int u) { for (int v = 1; v <= m; ++v) { if (!vis[v] && graph[u][v]) { vis[v] = 1; if (!match[v] || dfs(match[v])) { match[v] = u; link[u] = v; return 1; } } } return 0; } int hungary() { int res = 0; memset(match, 0, sizeof(match)); for (int u = 1; u <= n; ++u) { memset(vis, 0, sizeof(vis)); if (dfs(u)) res++; } return res; } int main() { // 读取数据,初始化图结构... // 读取n和m的值... // 调用hungary函数求解匹配数... printf( 参考资源链接:[二分图匹配算法实现:匈牙利算法与KM算法](https://wenku.youkuaiyun.com/doc/601h4knr28?spm=1055.2569.3001.10343)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值