#include #include #include #include #include #include #include #include #include #include using namespace std; clock_t LIMIT = 4.4 * CLOCKS_PER_SEC; clock_t startTime; bool globalTimeFlag = true; bool haveTime() { if (!globalTimeFlag) return false; return globalTimeFlag = clock() - startTime < LIMIT; } // calculate score the way sumOfEdgesTillCurrent // if we remove pref edge sumOfEdgesTillCurrent, score, // sum is i*v[i] we start from last and the sum is v[n], v[n-1] + 2*v[n], v[n-2]+2*v[n-1]+3*v[n]; // we save v[i]+v[i+1]+..+v[n]. S = v[i]+2*v[i+1]+..+k*v[n]; if we remove v[i] then // sum will be S-v[i]+v[i+1]+... // so our dfs will be start from end and traverse paths. if we cannot continue we remove last node and go again // and save current best result and do so until we have time. int n, m; vector G[100000]; long long bestRes = 0; vector bestPath; long long iterations = 0; vector vis; vector curPath; long long curScore = 0, curSumVertices = 0; void dfsIter(int startVertex) { stack > stk;// first is vertex, second is nbIdx stk.push(make_pair(startVertex, -1+G[startVertex].size())); curSumVertices += startVertex+1; curScore += curSumVertices; vis[startVertex] = 1; curPath.push_back(startVertex); if (curScore > bestRes) { #ifdef LOCAL fprintf(stderr, "Improvement! Old: %lld, New: %lld\n", bestRes, curScore); #endif bestRes = curScore; bestPath = curPath; } while (stk.size()) { if (!haveTime()) break; int curVertex = stk.top().first; int nbIdx = stk.top().second; if (nbIdx < 0) { stk.pop(); curScore -= curSumVertices; curSumVertices -= curVertex+1; vis[curVertex] = 0; curPath.pop_back(); continue; } int nb = G[curVertex][nbIdx]; stk.pop(); stk.push(make_pair(curVertex, nbIdx-1)); if (vis[nb]) { continue; } // ok to go on curSumVertices += nb+1; curScore += curSumVertices; vis[nb] = 1; curPath.push_back(nb); stk.push(make_pair(nb, -1+G[nb].size())); if (curScore > bestRes) { #ifdef LOCAL fprintf(stderr, "Improvement! Old: %lld, New: %lld\n", bestRes, curScore); #endif bestRes = curScore; bestPath = curPath; } } } void dfs(int curVertex) { iterations++; curSumVertices += curVertex+1; curScore += curSumVertices; vis[curVertex] = 1; curPath.push_back(curVertex); if (curScore > bestRes) { #ifdef LOCAL fprintf(stderr, "Improvement! Old: %lld, New: %lld\n", bestRes, curScore); #endif bestRes = curScore; bestPath = curPath; } vector& nbs = G[curVertex]; int nbsSz = nbs.size(); for (int nbId = nbsSz-1; nbId >= 0; --nbId) { if (!haveTime()) break; int nb = nbs[nbId]; if (vis[nb]) continue; dfs(nb); } curScore -= curSumVertices; curSumVertices -= curVertex+1; vis[curVertex] = 0; curPath.pop_back(); } void dfsSol() { vis.resize(n); for (int i = n-1; i >= 0; --i) { if (!haveTime()) break; fill(vis.begin(), vis.end(), 0); curPath.clear(); curScore = 0, curSumVertices = 0; dfs(i); } reverse(bestPath.begin(), bestPath.end()); printf("%d\n", bestPath.size()); for (int i = 0; i < bestPath.size(); ++i) { printf("%d\n", bestPath[i]+1); } } void solve() { while (haveTime()) { iterations++; long long curRes = 0; vector curPath; vector vis(n); int curV = rand() % n; vis[curV] = 1; curPath.push_back(curV); while (true) { vector& nbs = G[curV]; int nbsSz = nbs.size(); bool foundUnvisNbr = false; int nbIdx = rand() % nbsSz; for (int i = 0; i < nbsSz; ++i) { nbIdx = (nbIdx + i) % nbsSz; if (vis[nbs[nbIdx]]) continue; foundUnvisNbr = true; break; } if (!foundUnvisNbr) break; curV = nbs[nbIdx]; vis[curV] = 1; curPath.push_back(curV); } for (int i = 0; i < curPath.size(); ++i) { curRes += (i+1) * (curPath[i] + 1); } if (curRes > bestRes) { #ifdef LOCAL fprintf(stderr, "Improvement! Old: %lld, New: %lld\n", bestRes, curRes); #endif bestRes = curRes; bestPath = curPath; } } #ifdef LOCAL fprintf(stderr, "Iterations: %lld\n", iterations); #endif printf("%d\n", bestPath.size()); for (int i = 0; i < bestPath.size(); ++i) { printf("%d\n", bestPath[i]+1); } } int main() { startTime = clock(); srand(2000003569); freopen("maxpath.in", "r", stdin); freopen("maxpath.out", "w", stdout); scanf("%d %d", &n, &m); int v1,v2; for (int i = 0; i < m; ++i) { scanf("%d %d", &v1, &v2); // subtract one because the input is 1 based. v1--;v2--; G[v1].push_back(v2); G[v2].push_back(v1); } //solve(); dfsSol(); /* int i = 0; printf("Start waiting...\n"); while (haveTime()) { if (i++%100000000 == 0) printf("%d\n", i); } printf("Waited %.3lf seconds.\n", LIMIT / (double) CLOCKS_PER_SEC); */ return 0; }