Виталий Павленко ЮграНефтеТранс(Частичное решение) 115 #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include #include using namespace std; const int maxn = 2010; const int maxm = 100100; const double T0 = 100; const int maxk = 50; double alpha = 0.99; struct solution { bool a[maxn]; int cost; }; int n, m, k, t = 0; double T = T0; pair edges[maxm]; vector< vector > adj(maxn, vector ()); solution curr, next, best; int a[maxk]; bool b[maxn]; void check() { bool flag = true; for (int i = 0; i < m; ++i) flag = flag && (b[edges[i].first] || b[edges[i].second]); if (flag) { printf("Yes\n"); for (int i = 1; i <= k; ++i) printf("%d ", a[i] + 1); exit(0); } } void rec(int level) { for (int i = a[level - 1] + 1; i < n; ++i) { a[level] = i; b[i] = true; if (level < k) { rec(level + 1); } else { check(); } b[i] = false; } } void alternate() { a[0] = -1; for(int i = 0; i < n; ++i) b[i] = false; rec(1); } void setcost(solution& sol) { sol.cost = m; for(int i = 0; i < m; ++i) { if (sol.a[edges[i].first] || sol.a[edges[i].second]) sol.cost--; } } int calcbadedges(int vertex, solution& sol) { int res = 0; for(int i = 0; i < int(adj[vertex].size()); i++) { if (!(sol.a[edges[adj[vertex][i]].first] || sol.a[edges[adj[vertex][i]].second])) res++; } return res; } void setnext(solution& sol) { int before, after; for(int cnt = 0; cnt <= T; ++cnt) { int a = rand() % n, b = rand() % n; before = calcbadedges(a, sol) + calcbadedges(b, sol); swap(sol.a[a], sol.a[b]); after = calcbadedges(a, sol) + calcbadedges(b, sol); sol.cost -= before - after; } // setcost(sol); } bool admit(int dF) { return dF < 0 || exp(-dF / T) > rand() / double(RAND_MAX); } int main() { clock_t start = clock(); srand(3271); // freopen("pipeline.in", "r", stdin); // freopen("pipeline.out", "w", stdout); scanf("%d%d%d", &n, &m, &k); for(int i = 0; i < m; ++i) { scanf("%d%d", &edges[i].first, &edges[i].second); edges[i].first--; edges[i].second--; adj[edges[i].first].push_back(i); adj[edges[i].second].push_back(i); } if (m * pow(double(n), k) < 10000000) { cerr << "brute force\n"; alternate(); printf("No\n"); return 0; } cerr << "annealing\n"; T = n; alpha = pow(1 / T, m / 1200000.0); // printf("alpha: %f\n", alpha); for(int i = 0; i < k; ++i) { curr.a[i] = true; } for(int i = k; i < n; ++i) { curr.a[i] = false; } setcost(curr); best = curr; int t = 0; while(best.cost > 0) { t++; next = curr; setnext(next); if (admit(next.cost - curr.cost)) { curr = next; if (curr.cost < best.cost) best = curr; } if (t > (1000000.0 / m) / 1000) { if ((clock() - start) / double(CLOCKS_PER_SEC) > 1.95) { printf("No\n"); // printf("t = %d, T = %f\n", t, T); return 0; } } t++; T *= alpha; } //printf("t = %d, T = %f\n", t, T); printf("Yes\n"); for(int i = 0; i < n; ++i) if (best.a[i]) printf("%d ", i + 1); scanf("\n"); return 0; }