File size: 3,494 Bytes
1fd0050 | 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 128 129 130 131 | #include <bits/stdc++.h>
using namespace std;
const int MAXN = 500000;
int parent[MAXN], sizeComp[MAXN], nxt[MAXN], prv[MAXN], compStart[MAXN], compEnd[MAXN];
bool isEndpoint[MAXN];
int find(int x) {
return parent[x] == x ? x : parent[x] = find(parent[x]);
}
void reverseComponent(int r) {
int cur = compStart[r];
while (cur != -1) {
swap(nxt[cur], prv[cur]);
cur = prv[cur]; // after swap, prv holds the original next
}
swap(compStart[r], compEnd[r]);
}
void merge(int u, int v, int ru, int rv) {
nxt[u] = v;
prv[v] = u;
isEndpoint[u] = false;
isEndpoint[v] = false;
int start_u = compStart[ru];
int end_v = compEnd[rv];
if (sizeComp[ru] < sizeComp[rv]) {
swap(ru, rv);
}
parent[rv] = ru;
sizeComp[ru] += sizeComp[rv];
compStart[ru] = start_u;
compEnd[ru] = end_v;
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
vector<int> a(10);
for (int i = 0; i < 10; ++i) scanf("%d", &a[i]); // ignored in the algorithm
vector<pair<int, int>> edges;
for (int i = 0; i < m; ++i) {
int u, v;
scanf("%d %d", &u, &v);
--u; --v;
edges.emplace_back(u, v);
}
// sort edges by destination, then source
sort(edges.begin(), edges.end(), [](const pair<int, int>& p1, const pair<int, int>& p2) {
if (p1.second != p2.second) return p1.second < p2.second;
return p1.first < p2.first;
});
// initialize DSU and path structures
for (int i = 0; i < n; ++i) {
parent[i] = i;
sizeComp[i] = 1;
nxt[i] = -1;
prv[i] = -1;
isEndpoint[i] = true;
compStart[i] = i;
compEnd[i] = i;
}
// up to 10 passes
for (int iter = 0; iter < 10; ++iter) {
bool changed = false;
for (const auto& e : edges) {
int u = e.first, v = e.second;
int ru = find(u), rv = find(v);
if (ru == rv) continue;
if (!isEndpoint[u] || !isEndpoint[v]) continue;
bool u_start = (prv[u] == -1);
bool u_end = (nxt[u] == -1);
bool v_start = (prv[v] == -1);
bool v_end = (nxt[v] == -1);
if (u_end && v_start) {
merge(u, v, ru, rv);
changed = true;
} else if (u_start && v_end) {
reverseComponent(ru);
reverseComponent(rv);
merge(u, v, ru, rv);
changed = true;
} else if (u_end && v_end) {
reverseComponent(rv);
merge(u, v, ru, rv);
changed = true;
} else if (u_start && v_start) {
reverseComponent(ru);
merge(u, v, ru, rv);
changed = true;
}
}
if (!changed) break;
}
// find the largest component
int bestRoot = -1, bestSize = 0;
for (int i = 0; i < n; ++i) {
if (find(i) == i) {
if (sizeComp[i] > bestSize) {
bestSize = sizeComp[i];
bestRoot = i;
}
}
}
// reconstruct the path
vector<int> path;
int cur = compStart[bestRoot];
while (cur != -1) {
path.push_back(cur);
cur = nxt[cur];
}
// output
printf("%d\n", (int)path.size());
for (size_t i = 0; i < path.size(); ++i) {
if (i) printf(" ");
printf("%d", path[i] + 1);
}
printf("\n");
return 0;
} |