题意:给你n个正整数,一对和为素数的数为一个合法数对。你选不超过K个合法数对,使得你选的数对涉及到的数的数量最大化。输出这个值。

所有1之间是可以任意两两配对的。

把奇数放在左侧,偶数放在右侧。

考虑当前要使用多少个“1”,动态更新最大匹配。

如果K不超过 最大匹配数 + 剩下的还没使用过的1数/2 ,那么直接输出这个和*2即可。

否则剩下的用剩余的1(最多一个)+没被匹配上的但是不孤立(有边)的点数 补齐,这样不断更新答案。

有一个坑点是如果1恰好只有一个的话,而且没有能和它加起来组成素数的数的话,就要忽略掉这个1。

#include<cstdio>
#include<algorithm>
#include<cstring>
typedef long long ll;
using namespace std;
int T,n,K,a[3005];
bool notprime[2000005];
bool cmp(const int &a,const int &b){
return a>b;
}
int e,first[3005],next[3005*3005],v[3005*3005];
void AddEdge(int U,int V){
v[++e]=V;
next[e]=first[U];
first[U]=e;
}
int mat[3005],yi;
bool vis[3005];
bool dfs(int U)
{
for(int i=first[U];i;i=next[i]){
if(!vis[v[i]]){
vis[v[i]]=1;
if(mat[v[i]]==-1 || dfs(mat[v[i]])){
mat[v[i]]=U;
return 1;
}
}
}
return 0;
}
int ru[3005],ru1[3005],right1,right2;
int main(){
notprime[1]=1;
for(int i=2;i<=2000000;++i){
for(ll j=(ll)i*(ll)i;j<=2000000ll;j+=(ll)i){
notprime[j]=1;
}
}
scanf("%d",&T);
for(;T;--T){
e=0;
memset(mat,-1,sizeof(mat));
memset(first,0,sizeof(first));
memset(ru,0,sizeof(ru));
memset(ru1,0,sizeof(ru1));
scanf("%d%d",&n,&K);
yi=0;
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
if(a[i]==1){
++yi;
}
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
if(!(a[i]==1 && a[j]==1) && !notprime[a[i]+a[j]]){
if(a[i]&1){
AddEdge(i,j);
++ru[j];
if(a[i]==1){
++ru1[j];
}
}
else{
AddEdge(j,i);
++ru[i];
if(a[j]==1){
++ru1[i];
}
}
}
}
}
bool tp=(yi==1 ? 1 : 0);
right1=right2=0;
for(int i=1;i<=n;++i){
if(!(a[i]&1)){
if(ru[i]>ru1[i]){
++right1;
}
if(ru[i]){
++right2;
}
if(ru1[i]){
tp=0;
}
}
}
if(tp){
yi=0;
}
int sum=0,cnt=0,nowleft=0,ans=0;
for(int i=1;i<=n;++i){
if((a[i]&1)){
++nowleft;
if(a[i]!=1 && first[i]){
memset(vis,0,sizeof(vis));
if(dfs(i)){
++sum;
}
}
else if(a[i]==1 && !tp){
if(!cnt){
if(K<=sum+yi/2){
ans=max(ans,2*K);
}
else{
ans=max(ans,2*sum+yi+min(K-sum-yi/2-yi%2,nowleft-1+right1-sum*2));
}
}
++cnt;
memset(vis,0,sizeof(vis));
if(dfs(i)){
++sum;
}
if(K<=sum+(yi-cnt)/2){
ans=max(ans,2*K);
}
else{
ans=max(ans,2*sum+(yi-cnt)+min(K-sum-(yi-cnt)/2-(yi-cnt)%2,nowleft+right2-sum*2));
}
}
}
}
if(!cnt){
if(K<=sum){
ans=max(ans,2*K);
}
else{
ans=max(ans,2*sum+min(K-sum,nowleft+right1-sum*2));
}
}
printf("%d\n",ans);
}
return 0;
}

【二分图最大匹配】【匈牙利算法】zoj3988 Prime Set的更多相关文章

  1. UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法

    二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...

  2. Ural1109_Conference(二分图最大匹配/匈牙利算法/网络最大流)

    解题报告 二分图第一题. 题目描写叙述: 为了參加即将召开的会议,A国派出M位代表,B国派出N位代表,(N,M<=1000) 会议召开前,选出K队代表,每对代表必须一个是A国的,一个是B国的; ...

  3. HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...

  4. HDU1068 (二分图最大匹配匈牙利算法)

    Girls and Boys Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. poj - 3041 Asteroids (二分图最大匹配+匈牙利算法)

    http://poj.org/problem?id=3041 在n*n的网格中有K颗小行星,小行星i的位置是(Ri,Ci),现在有一个强有力的武器能够用一发光速将一整行或一整列的小行星轰为灰烬,想要利 ...

  6. 二分图最大匹配(匈牙利算法) POJ 3041 Asteroids

    题目传送门 /* 题意:每次能消灭一行或一列的障碍物,要求最少的次数. 匈牙利算法:把行和列看做两个集合,当有障碍物连接时连一条边,问题转换为最小点覆盖数==二分图最大匹配数 趣味入门:http:// ...

  7. HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)

    (点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配 ...

  8. 51Nod 2006 飞行员配对(二分图最大匹配)-匈牙利算法

    2006 飞行员配对(二分图最大匹配) 题目来源: 网络流24题 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 第二次世界大战时期,英国皇家空军从沦陷国 ...

  9. poj 3894 System Engineer (二分图最大匹配--匈牙利算法)

    System Engineer Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 507   Accepted: 217 Des ...

  10. POJ1274:The Perfect Stall(二分图最大匹配 匈牙利算法)

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17895   Accepted: 814 ...

随机推荐

  1. 【译】DTD - Entities

    原文:DTD - Entities 实体用于定义XML文档中特殊字符的快捷方式. 实体主要有四种类型: 内置实体(Built-in entities) 字符实体(Character entities) ...

  2. HTTP、HTTPS

    http是一种无状态协议,通过短暂保持浏览器核服务器间通信可以有效减少为保持连接而耗费的额外开销.无状态意味着浏览器和服务器完成一次通信后,连接会释放.在下一次会话发起时,浏览器核服务器端不会记录上一 ...

  3. 远程工具(SSH Secure)连接Centos出现中文乱码问题的解决办法

    问题原因 使用远程工具进行连接时,如果linux有中文文件或目录,显示时会出现乱码,原因是linux编码是UTF-8,而远程工具默认是当前系统本地编码即GBK.所以解决方案是统一两者编码就OK了,但是 ...

  4. webconfig的配置解析

    <?xml version="1.0"?> <!--注意: 除了手动编辑此文件以外,您还可以使用 Web 管理工具来配置应用程序的设置.可以使用 Visual S ...

  5. http 错误代码解释 && nginx 自定义错误【转】

    如果向您的服务器发出了某项请求要求显示您网站上的某个网页(例如,当用户通过浏览器访问您的网页或在 Googlebot 抓取该网页时),那么,您的服务器会返回 HTTP 状态代码以响应该请求. 此状态代 ...

  6. Python排序算法之插入排序

    # 插入排序的工作原理是,对于每个未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入.## 步骤:## 从第一个元素开始,该元素可以认为已经被排序# 取出下一个元素,在已经排序的元素序列中从后 ...

  7. OAuth认证与授权

    什么是OAuth授权?   一.什么是OAuth协议 OAuth(开放授权)是一个开放标准. 允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息. 而这种授权无需将用户提供用户名和密 ...

  8. WPF之换肤

    WPF之换肤 设计原理 WPF换肤的设计原理,利用资源字典为每种皮肤资源添加不同的样式,在后台切换皮肤资源文件. 截图 上图中,第一张图采用规则样式,第二张图采用不规则样式,截图的时候略有瑕疵. 资源 ...

  9. Java容器---Collection接口中的共有方法

    1.Collection 接口 (1)Collection的超级接口是Iterable (2)Collection常用的子对象有:Map.List.Set.Queue. 右图中实现黑框的ArrayLi ...

  10. [重磅]Deep Forest,非神经网络的深度模型,周志华老师最新之作,三十分钟理解!

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 深度学习最大的贡献,个人认为就是表征 ...