//Algorytm łazarski - tak brutalny, że od samego gapienia się można dostać bejsbolem #include <stdio.h> #include <vector> #include <algorithm> using namespace std; const int C=1001, Inf = 1000000000; bool on_stack[C]; int stack[C]; int find_mvc_with_marked_vertex(int marked, vector <vector <int> > &gr, int n, int m, int k, vector<pair<int,int>> params){ vector<pair<int,int>> post_params; for (auto x: params){ if (x.second != marked) post_params.push_back(x); } for (int i=0; i<=n; i++) on_stack[i] = false; on_stack[marked] = true; int is = 1; stack[0] = marked; int found_edges = gr[marked].size(); int best_result = Inf; int cur_index = 0; if (found_edges == m) return 1; while (true){ int next_element = post_params[cur_index].second; stack[is] = next_element; on_stack[stack[is]] = true; is++; cur_index++; for (auto &x: gr[next_element]){ if (!on_stack[x]) found_edges++; } //for (auto &x: post_params) printf ("%d", on_stack[x.second]); //printf ("\n"); //printf ("stack size: %d\n", is); if (found_edges == m) best_result = is; if (is >= std::min(k, best_result) || cur_index == post_params.size()){ //Ulepszyć warunek -> tutaj zachodzi nawrót - bez marka, to będzie dalej if (cur_index < post_params.size()){ int a = post_params[cur_index-1].second; for (auto &x: gr[a]){ if (!on_stack[x]) found_edges--; } on_stack[a] = false; is--; } else{ cur_index--; for (; cur_index>=0; cur_index--){ int a = post_params[cur_index].second; if (on_stack[a]){ is--; for (auto &x: gr[a]){ if (!on_stack[x]) found_edges--; } on_stack[a] = false; } else break; } for (; cur_index>=0; cur_index--){ int a = post_params[cur_index].second; if (on_stack[a]){ is--; for (auto &x: gr[a]){ if (!on_stack[x]) found_edges--; } on_stack[a] = false; break; } } if (cur_index < 0) return best_result; cur_index++; } } if (cur_index < 0) return best_result; } return best_result; } vector <vector <int>> edges(C); int res[C]; int main(){ int t; scanf ("%d", &t); while (t--){ int n, m, k; vector<pair<int, int>> params; vector <int> final_results; scanf ("%d %d %d", &n, &m, &k); for (int i=1; i<=n; i++) edges[i].clear(); for (int i=0; i<m; i++){ int a, b; scanf ("%d %d", &a, &b); edges[a].push_back(b); edges[b].push_back(a); } for (int i=1; i<=n; i++) params.push_back({-edges[i].size(), i}); sort(params.begin(), params.end()); int min_result = Inf; for (int i=1; i<=n; i++){ res[i] = find_mvc_with_marked_vertex(i, edges, n, m, std::min(k, min_result), params); if (res[i] <= min_result) min_result = res[i]; } if (min_result > k) printf ("-1\n"); else { for (int i=1; i<=n; i++){ if (res[i] == min_result) final_results.push_back(i); } printf ("%d %lu\n", min_result, final_results.size()); for (auto &x: final_results) printf ("%d ", x); printf ("\n"); } } return 0;}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | //Algorytm łazarski - tak brutalny, że od samego gapienia się można dostać bejsbolem #include <stdio.h> #include <vector> #include <algorithm> using namespace std; const int C=1001, Inf = 1000000000; bool on_stack[C]; int stack[C]; int find_mvc_with_marked_vertex(int marked, vector <vector <int> > &gr, int n, int m, int k, vector<pair<int,int>> params){ vector<pair<int,int>> post_params; for (auto x: params){ if (x.second != marked) post_params.push_back(x); } for (int i=0; i<=n; i++) on_stack[i] = false; on_stack[marked] = true; int is = 1; stack[0] = marked; int found_edges = gr[marked].size(); int best_result = Inf; int cur_index = 0; if (found_edges == m) return 1; while (true){ int next_element = post_params[cur_index].second; stack[is] = next_element; on_stack[stack[is]] = true; is++; cur_index++; for (auto &x: gr[next_element]){ if (!on_stack[x]) found_edges++; } //for (auto &x: post_params) printf ("%d", on_stack[x.second]); //printf ("\n"); //printf ("stack size: %d\n", is); if (found_edges == m) best_result = is; if (is >= std::min(k, best_result) || cur_index == post_params.size()){ //Ulepszyć warunek -> tutaj zachodzi nawrót - bez marka, to będzie dalej if (cur_index < post_params.size()){ int a = post_params[cur_index-1].second; for (auto &x: gr[a]){ if (!on_stack[x]) found_edges--; } on_stack[a] = false; is--; } else{ cur_index--; for (; cur_index>=0; cur_index--){ int a = post_params[cur_index].second; if (on_stack[a]){ is--; for (auto &x: gr[a]){ if (!on_stack[x]) found_edges--; } on_stack[a] = false; } else break; } for (; cur_index>=0; cur_index--){ int a = post_params[cur_index].second; if (on_stack[a]){ is--; for (auto &x: gr[a]){ if (!on_stack[x]) found_edges--; } on_stack[a] = false; break; } } if (cur_index < 0) return best_result; cur_index++; } } if (cur_index < 0) return best_result; } return best_result; } vector <vector <int>> edges(C); int res[C]; int main(){ int t; scanf ("%d", &t); while (t--){ int n, m, k; vector<pair<int, int>> params; vector <int> final_results; scanf ("%d %d %d", &n, &m, &k); for (int i=1; i<=n; i++) edges[i].clear(); for (int i=0; i<m; i++){ int a, b; scanf ("%d %d", &a, &b); edges[a].push_back(b); edges[b].push_back(a); } for (int i=1; i<=n; i++) params.push_back({-edges[i].size(), i}); sort(params.begin(), params.end()); int min_result = Inf; for (int i=1; i<=n; i++){ res[i] = find_mvc_with_marked_vertex(i, edges, n, m, std::min(k, min_result), params); if (res[i] <= min_result) min_result = res[i]; } if (min_result > k) printf ("-1\n"); else { for (int i=1; i<=n; i++){ if (res[i] == min_result) final_results.push_back(i); } printf ("%d %lu\n", min_result, final_results.size()); for (auto &x: final_results) printf ("%d ", x); printf ("\n"); } } return 0;} |