fork(2) download
  1. #include <cstdio>
  2. #include <vector>
  3. #include <queue>
  4. #include <limits>
  5. #include <algorithm>
  6. using namespace std;
  7. struct NetworkFlow {
  8. struct Edge {
  9. int target, inverse_index;
  10. int capacity, flow;
  11. Edge(int t, int c, int ii) : target(t), capacity(c), flow(0), inverse_index(ii) {}
  12. int residual() const { return capacity - flow; }
  13. };
  14. int V;
  15. vector< vector<Edge> > adj;
  16. vector<int> levels, edges_tried;
  17.  
  18. NetworkFlow(int V) : V(V), adj(V), levels(V), edges_tried(V) {}
  19.  
  20. void add_edge(int a, int b, int a2b, int b2a = 0) {
  21. int a2b_index = adj[a].size(), b2a_index = adj[b].size();
  22. adj[a].push_back(Edge(b, a2b, b2a_index));
  23. adj[b].push_back(Edge(a, b2a, a2b_index));
  24. }
  25.  
  26. bool assign_levels(int source, int sink) {
  27. fill(levels.begin(), levels.end(), -1);
  28. queue<int> q; q.push(source);
  29. levels[source] = 0;
  30. while (!q.empty()) {
  31. int here = q.front(); q.pop();
  32. for (int i = 0; i < adj[here].size(); ++i) {
  33. const Edge& e = adj[here][i];
  34. if (levels[e.target] == -1 && e.residual() > 0) {
  35. levels[e.target] = levels[here] + 1;
  36. q.push(e.target);
  37. }
  38. }
  39. }
  40. return levels[sink] != -1;
  41. }
  42.  
  43. int push_flow(int here, int sink, int flow) {
  44. if (here == sink) return flow;
  45.  
  46. for (int& i = edges_tried[here]; i < adj[here].size(); ++i) {
  47. Edge& e = adj[here][i];
  48. if (e.residual() > 0 && levels[e.target] == levels[here] + 1) {
  49. int amt = push_flow(e.target, sink, min(flow, e.residual()));
  50. if (amt > 0) {
  51. Edge& e_inv = adj[e.target][e.inverse_index];
  52. e.flow += amt;
  53. e_inv.flow = -e.flow;
  54. return amt;
  55. }
  56. }
  57. }
  58. return 0;
  59. }
  60.  
  61. int go(int source, int sink) {
  62. int total_flow = 0;
  63. while (assign_levels(source, sink)) {
  64. fill(edges_tried.begin(), edges_tried.end(), 0);
  65. while (true) {
  66. int pushed = push_flow(source, sink, numeric_limits<int>::max());
  67. if (pushed == 0) break;
  68. total_flow += pushed;
  69. }
  70. }
  71. return total_flow;
  72. }
  73. };
  74. bool isprime[2005];
  75. int main() {
  76. int n;
  77. for (int i = 2; i <= 2000; i++) isprime[i] = 1;
  78. for (int i = 2; i <= 2000; i++) {
  79. if (isprime[i] == 1) {
  80. for (int j = i + i; j <= 2000; j += i) isprime[j] = 0;
  81. }
  82. }
  83. scanf("%d", &n);
  84. vector <int> v, res;
  85. v.resize(n);
  86. for (int i = 0; i < n; i++) scanf("%d", &v[i]);
  87. for (int i = 1; i < n; i++) {
  88. if (isprime[v[0] + v[i]]) {
  89. vector <int> x;
  90. x.push_back(0);
  91. for (int k = 1; k < n; k++) {
  92. if (k == i) continue;
  93. x.push_back(v[k]);
  94. }
  95. int m = n - 2;
  96. NetworkFlow f(2 * m + 2);
  97. for (int k = 1; k <= m; k++) {
  98. f.add_edge(0, k, 1, 0);
  99. f.add_edge(m + k, 2 * m + 1, 1, 0);
  100. for (int l = 1; l <= m; l++) {
  101. if (k == l) continue;
  102. if (isprime[x[k] + x[l]]) f.add_edge(k, m + l, 1, 0);
  103. }
  104. }
  105. int flow = f.go(0, 2 * m + 1);
  106. if (flow == m) res.push_back(v[i]);
  107. }
  108. }
  109. sort(res.begin(), res.end());
  110. if (res.size() == 0) puts("-1");
  111. else {
  112. for (int i = 0; i < res.size(); i++) {
  113. printf("%d ", res[i]);
  114. }
  115. }
  116. }
Success #stdin #stdout 0s 3488KB
stdin
6
1 4 7 10 11 12
stdout
4 10