标签:define 不难 init style memset lse 最大 坑点 ini
思路不难想到二分图求个最大匹配P,若P>=K,则2*K即可,否则应为P*2+min(K-P,未匹配且有度数不为0的顶点个数s)。但坑点在于有1的情况,所以如果直接建二分图去跑最大匹配会因为1的影响而无法得到实际上的最大匹配,所以索性不建二分图而直接去跑最大匹配,此时应记录的是每个顶点的匹配顶点即可。
#include<cstdio> #include<cstdlib> #include<iostream> #include<string> #include<set> #include<algorithm> #include<vector> #include<queue> #include<list> #include<cmath> #include<cstring> #include<map> #include<stack> using namespace std; #define INF 0x3f3f3f3f #define maxn 2000005 #define ull unsigned long long #define ll long long #define hashmod 99999839 #define mod 9997 bool isprim[maxn],f[3005]; int pre[3005]; int prim[maxn],len,a[3005]; vector<int> vec[3005]; void init(){ for(int i = 2;i < maxn;i++) isprim[i] = true; for(int i = 2;i < maxn;++i){ if(isprim[i]) prim[len++] = i; for(int j = 0;j < len;++j){ if(i * prim[j] > maxn) break; isprim[i * prim[j]] = false; if(i % prim[j] == 0) break; } } } bool dfs(int v){//尝试匹配v f[v] = true; for(int i = 0;i < vec[v].size();++i){ int t = vec[v][i]; if(!f[t]){ f[t] = true; if(!pre[t] || dfs(pre[t])){ pre[t] = v; pre[v] = t; f[t] = false; f[v] = false; return true; } } } return false; } int main(){ // freopen("a.in","r",stdin); // freopen("b.out","w",stdout); init(); int T; cin >> T; int n,k; while(T--){ scanf("%d%d",&n,&k); for(int i = 1;i <= n;++i){ scanf("%d",&a[i]); } sort(a + 1,a + n + 1); for(int i = 1;i <= n;++i){ for(int j = i + 1;j <= n;++j){ if(isprim[a[i] + a[j]]) vec[i].push_back(j),vec[j].push_back(i); } } memset(f,false,sizeof(f)); memset(pre,0,sizeof(pre)); int ans = 0; for(int i = 1;i <= n;++i){ if(!pre[i] && !f[i] && dfs(i)){ ans++; } } if(ans >= k) ans = k * 2; else{ k -= ans; ans = ans * 2; for(int i = 1;i <= n && k;++i){ if(!pre[i]){ int sz = vec[i].size(); if(sz) k--,ans++; } } } for(int i = 1;i <= n;++i) vec[i].clear(); printf("%d\n",ans); } return 0; }
标签:define 不难 init style memset lse 最大 坑点 ini
原文地址:https://www.cnblogs.com/zhuiyicc/p/9514958.html