sxhy @ 2024-03-30 17:23:28
stl的栈100分
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
int n, m, dfn[N], low[N],cnt, tot, top, cut[N];
int root;
struct edge {
int u, v;
};
vector<edge>e;
vector<int>h[2 * N], edcc[N];
stack<int>stk;
void add(int a, int b) {
e.push_back({ a,b });
h[a].push_back(e.size() - 1);
}
void tarjan(int x, int inedge) {
dfn[x] = low[x] = ++tot;
stk.push(x);
for (int i = 0; i < h[x].size(); i++) {
int bian = h[x][i], v = e[bian].v;
if (!dfn[v]) {
tarjan(v, bian);
low[x] = min(low[x], low[v]);
if (low[v] > dfn[x]) {
cut[bian] = cut[(bian ^ 1)] = 1;
}
}
else if (bian != (inedge ^ 1)) {
low[x] = min(low[x], dfn[v]);
}
}
if (low[x] == dfn[x]) {
int y;
cnt++;
while (1) {
y = stk.top(), stk.pop();
edcc[cnt].push_back(y);
if (y == x)break;
}
}
}
int main() {
int a, b;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> a >> b;
add(a, b), add(b, a);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])tarjan(i, 0);
}
cout << cnt << "\n";
for (int i = 1; i <= cnt; i++) {
cout << edcc[i].size() << " ";
for (int j = 0; j < edcc[i].size(); j++) {
cout << edcc[i][j] << " ";
}
puts("");
}
}
手写栈89分
#include<bits/stdc++.h>
using namespace std;
const int N = 2e6 + 10;
int n, m, dfn[N], low[N], stk[N], cnt, tot, top, cut[N];
int root;
struct edge {
int u, v;
};
vector<edge>e;
vector<int>h[2 * N], edcc[N];
void add(int a, int b) {
e.push_back({ a,b });
h[a].push_back(e.size() - 1);
}
void tarjan(int x, int inedge) {
dfn[x] = low[x] = ++tot;
stk[++top] = x;
for (int i = 0; i < h[x].size(); i++) {
int bian = h[x][i], v = e[bian].v;
if (!dfn[v]) {
tarjan(v, bian);
low[x] = min(low[x], low[v]);
if (low[v] > dfn[x]) {
cut[bian] = cut[(bian ^ 1)] = 1;
}
}
else if (bian != (inedge ^ 1)) {
low[x] = min(low[x], dfn[v]);
}
}
if (low[x] == dfn[x]) {
int y;
cnt++;
while (1) {
y = stk[top];
top--;
edcc[cnt].push_back(y);
if (y == x)break;
}
}
}
int main() {
int a, b;
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> a >> b;
add(a, b), add(b, a);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])tarjan(i, 0);
}
cout << cnt << "\n";
for (int i = 1; i <= cnt; i++) {
cout << edcc[i].size() << " ";
for (int j = 0; j < edcc[i].size(); j++) {
cout << edcc[i][j] << " ";
}
puts("");
}
}
by DAMDAM @ 2024-03-30 18:34:13
N
开大点就过了。。。 @sxhy
by DAMDAM @ 2024-03-30 18:35:53
因为边表要开两倍,cut
数组跟着也要开两倍
by Rosick @ 2024-03-30 18:37:23
cut数组没用,且超限了,如果手写栈,就会修改到里面的内容,而stl的不会 @sxhy
by sxhy @ 2024-03-30 18:40:20
@DAMDAM 感谢!我超,什么原理
by Atri_Lobato @ 2024-08-27 10:04:26
@sxhy 正反边建两次qaq我也错了