题解 | #素数伴侣#
素数伴侣
https://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
#include <cmath>
#include <iostream>
#include <iterator>
#include <vector>
#include "bits/stdc++.h"
using namespace std;
bool nodiv(uint64_t num, std::unordered_set<int>& divnt) {
if (divnt.count(num)) {
return true;
}
const int a = sqrt(num);
bool is_true = true;
for (int i = 2; i <= a; ++i) {
if (!(num % i)) {
return false;
}
}
divnt.insert(num);
return is_true;
}
enum class color {
white,
gray,
black
};
struct vertex {
//parent
int p = -1;
//color
color c = color::white;
//distance
int d = 0;
};
struct fc {
int f = -1;
int c = -1;
int cfp = std::numeric_limits<int>::max();
};
std::vector<vertex> bfs(std::vector<std::vector<fc>>& graph, int s, int t) {
std::vector<vertex> hoge(graph.size());
hoge[s].c = color::gray;
std::queue<int> queue;
queue.push(s);
while (!queue.empty()) {
const auto u = queue.front();
queue.pop();
for (int i = 0; i < graph.size(); ++i) {
auto new_c_uv = 0;
if (graph[u][i].c > 0 && graph[u][i].f >= 0) {
new_c_uv = graph[u][i].c - graph[u][i].f;
} else if (graph[i][u].c > 0 && graph[i][u].f >= 0) {
new_c_uv = graph[i][u].f;
}
graph[u][i].cfp = new_c_uv;
if (new_c_uv > 0 && hoge[i].c == color::white) {
hoge[i].c = color::gray;
hoge[i].d = hoge[u].d + 1;
hoge[i].p = u;
queue.push(i);
}
}
hoge[u].c = color::black;
}
return hoge;
}
int max_prime_number(std::vector<std::vector<fc>>& graph, int s, int t) {
int v;
for (int i = 0; i < graph.size(); ++i) {
for (int j = 0; j < graph[i].size(); ++j) {
if (graph[i][j].c > 0) {
graph[i][j].f = 0;
}
}
}
int sum = 0;
while (true) {
auto cp = std::numeric_limits<int>::max();
auto cc = bfs(graph, s, t);
int i1 = t;
std::vector<std::pair<int, int>> edges;
while (cc[i1].p >= 0) {
int u = cc[i1].p;
cp = std::min(cp, graph[u][i1].cfp);
edges.push_back({u, i1});
i1 = u;
}
if (i1 != 0) {
int a = 0;
std::vector<std::pair<int, int>> av ;
for (int i = 1; i < graph.size() - 1; ++i) {
for (int j = 1; j < graph[i].size() - 1; ++j) {
if (graph[i][j].c == 1 && graph[i][j].f == 1) {
a += graph[i][j].f;
av.push_back({i, j});
}
}
}
break;
}
for (auto&& [u, v] : edges) {
if (graph[u][v].c >= 0 && graph[u][v].f >= 0 ) {
graph[u][v].f = graph[u][v].f + cp;
} else {
graph[v][u].f = graph[v][u].f - cp;
}
}
sum += cp;
}
return sum;
}
int main() {
int a = 0;
std::unordered_set<int> divnt;
while (std::cin >> a) {
// 注意 while 处理多个 case
std::unordered_map<int, int> odd;
std::unordered_map<int, int> even;
for (int i = 1; i <= a; ++i) {
int b;
std::cin >> b;
if (b % 2) {
odd[i] = b;
} else {
even[i] = b;
}
}
int sum = 0;
std::vector<std::vector<fc>> graph(a + 2, std::vector<fc>(a + 2, fc{}));
for (auto&& [key, value] : odd) {
for (auto&& [key2, value2] : even) {
if (nodiv(value + value2, divnt)) {
graph[key][key2].c = 1;
++sum;
}
}
}
//s->odd
for (std::pair<int, int> value : odd ) {
graph[0][value.first].c = 1;
}
//even->t
for (std::pair<int, int> value : even) {
graph[value.first][a + 1].c = 1;
}
std::cout << max_prime_number(graph, 0, a + 1) << std::endl;
}
}
// 64 位输出请用 printf("%lld")
压根不会,翻书才做出来了,用的ford-fulkerson algorithm 照着算法导论实现的