您的位置:首页 > 其它

牛客网 素数伴侣(二分图最大匹配,匈牙利算法)

2017-05-01 13:51 435 查看
题目链接:https://www.nowcoder.com/questionTerminal/b9eae162e02f4f928eac37d7699b352e

解题方案:2<=x,y<=30000,则4<=x+y<=60000,这个范围内只有奇数才有可能成为素数,而只有奇数+偶数=奇数,所以可以将n个数分成奇数和偶数两拨,然后可以相加凑成素数的则连上一条边,这样就转换成了二分图的最大匹配问题,可以用匈牙利算法。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>

using namespace std;

#define FOR(i,k,n) for(int i=k;i<n;i++)
#define FORR(i,k,n) for(int i=k;i<=n;i++)
#define scan(a) scanf("%d",&a)
#define scann(a,b) scanf("%d%d",&a,&b)
#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mst(a,n)  memset(a,n,sizeof(a))
#define ll long long
#define N 105
#define mod 1000000007
#define INF 0x3f3f3f3f

const double eps=1e-8;
const double pi=acos(-1.0);

int alen,blen;
int a
,b
,match
,check
,match1
;
int g

;
int ans;

bool Dfs(int u)
{
FOR(v,0,blen)
{
if(g[u][v])
{
if(!check[v])//v不在交替路中,此时u-v一定是一条非匹配边,因为u是非匹配点
{            //或u是匹配点且递归走匹配边过来的,而且已经将匹配边放入交替路了,而一个匹配点只会有一条匹配边
check[v]=1;//放入交替路
if(match[v]==-1||Dfs(match[v]))//到达未匹配点,说明此时交替路为增广路,则交换路径,并返回成功
{                              //或者到达匹配点,此时走匹配边v-match[v],若最后找到增广路,则交换路径,并返回成功
match[v]=u;
//match1[u]=v;
return true;
}
}
}
}
return false;
}

bool isPrime(int x)
{
for(int i=2;i<=sqrt(x);i++)
if(x%i==0) return false;
return true;
}

int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);

int n;
while(~scan(n))
{
alen=blen=0;
mst(match,-1); mst(g,0);

FOR(i,0,n)
{
int tmp;
scan(tmp);
if(tmp&1) a[alen++]=tmp;
else b[blen++]=tmp;
}
FOR(i,0,alen) FOR(j,0,blen) if(isPrime(a[i]+b[j])) g[i][j]=1;
ans=0;
FOR(i,0,alen)
{
//printf("***%d\n",match1[i]);
//此时i一定为非匹配点,因为每次Dfs返回成功的话都只会在二分图左右两边分别增加一个匹配点,增加一条匹配边
//二分图左边增加一个点i后,Dfs检查是否可以增加一条匹配边
           mst(check,0);
if(Dfs(i)) ans++;
}
printf("%d\n",ans);
}
return 0;
}

匈牙利算法中贪心思想(不断找增广路)的正确性证明:

https://liam0205.me/2016/04/03/Hungarian-algorithm-in-the-maximum-matching-problem-of-bigraph/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息