题意:给你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. iOS网络基础---iOS-Apple苹果官方文档翻译

    CHENYILONG Blog iOS网络基础---iOS-Apple苹果官方文档翻译 iOS网络基础 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http: ...

  2. 使用Skyworking 作全链路api调用监控,Integration of Skyworking, auditing the whole chain circuit.

    Applicable scenario: Structure Map ~ Skywalking uses elasticsearch to store data, don't mistake elas ...

  3. Tensorflow中使用TFRecords高效读取数据--结合Attention-over-Attention Neural Network for Reading Comprehension

    原文链接:https://arxiv.org/pdf/1607.04423.pdf 本片论文主要讲了Attention Model在完形填空类的阅读理解上的应用. 转载:https://blog.cs ...

  4. 服务器部署之nginx的配置

    nginx可作为Web和 反向代理 服务器,在高连接并发的情况下,Nginx是Apache服务器不错的替代品.下面记录一下自己对nginx的配置和使用. nginx的安装 环境:oracle-linu ...

  5. Django【进阶】modelform

    modelform:models+form   建议尽量用Djangoform,更灵活,但也有人用modelform,写起来很简单 缺点,在models里面,表模型必须有__str__()方法 可添加 ...

  6. 如何在Linux下用C/C++语言操作数据库sqlite3(很不错!设计编译链接等很多问题!)

    from : http://blog.chinaunix.NET/uid-21556133-id-118208.html 安装Sqlite3: 从www.sqlite.org上下载Sqlite3.2. ...

  7. linux配置samba服务【原创】

    转载请注明出处http://www.cnblogs.com/paul8339/p/7509981.html 需求,windows服务器访问linux的共享文件,需要linux服务器安装并配置samba ...

  8. Nginx源码分析--数组(转)

    原文地址:http://blog.csdn.net/marcky/article/details/5747431 备注:以下关于Nginx源码的分析基于淘宝开源项目Tengine. Nginx中对数组 ...

  9. hbase学习(二)hbase单机和高可用完全分布式安装部署

    hbase版本 2.0.4  与hadoop兼容表http://hbase.apache.org/book.html#hadoop  我的 hadoop版本是3.1   1.单机版hbase 1.1解 ...

  10. netty 基础知识

    http://my.oschina.net/bieber/blog/406799 线程模型 http://hongweiyi.com/2014/01/netty-4-x-thread-model/ h ...