强联通
#include <bits/stdc++.h>
using namespace std;
inline int read(int& x) {
char ch = getchar();
int f = 1; x = 0;
while (ch > '9' || ch < '0') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return nullptr; }();
const int maxn = 1e4 + 7;
struct TStack {
static const int TSMAXN = 1e4 + 7;
typedef int value_Type;
public:
TStack():nlen(0){}
public:
void push(value_Type input) {
data[nlen++] = input;
}
value_Type pop() {
if (nlen <= 0) return value_Type();
return data[--nlen];
}
int size() {
return nlen;
}
bool empty() {
return size() == 0;
}
value_Type data[TSMAXN];
int nlen;
};
TStack st;
int dfn[maxn], low[maxn], vis[maxn], color[maxn],id[maxn],d[maxn], c = 0, nTime = 0, n, m;
vector<int> e[maxn];
void tarjan(int x) {
dfn[x] = low[x] = ++nTime;
st.push(x);
vis[x] = 1;
for (auto& y : e[x]) {
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
}
else if (vis[y]) {
low[x] = min(low[x], dfn[y]);
}
}
if (dfn[x] == low[x]) {
c++;
int v;
do {
v = st.pop();
color[c]++;
vis[v] = 0;
id[v] = c;
} while (v != x);
}
}
void slove() {
cin >> n >> m;
int a, b;
for (int i = 1; i <= m; i++) {
cin >> a >> b;
e[a].push_back(b);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])tarjan(i);
}
for (int i = 1; i <= n; i++) {
for (auto& x : e[i]) {
if (id[i] != id[x]) {
d[id[i]]++;
}
}
}
int idx = 0;
for (int i = 1; i <= c; i++) {
if (d[i])continue;
if (idx) {
idx = 0;
break;
}
idx = i;
}
cout << color[idx] << endl;
}
int main() {
slove();
return 0;
}
P2746 [USACO5.3] 校园网Network of Schools
#include <bits/stdc++.h>
using namespace std;
inline int read(int& x) {
char ch = getchar();
int f = 1; x = 0;
while (ch > '9' || ch < '0') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return nullptr; }();
const int maxn = 1e2 + 7;
int n,dfn[maxn],low[maxn],vis[maxn],st[maxn],id[maxn],d[maxn],d2[maxn],stop = 0,nTime = 0,c = 0;
vector<int> e[maxn];
void tarjan(int x) {
dfn[x] = low[x] = ++nTime;
st[++stop] = x;
vis[x] = 1;
for (auto& y : e[x]) {
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
}
else if (vis[y]) low[x] = min(low[x], dfn[y]);
}
if (dfn[x] == low[x]) {
int v;
c++;
do {
v = st[stop--];
vis[v] = 0;
id[v] = c;
} while (v != x);
}
}
void slove() {
cin >> n;
int input;
for (int i = 1; i <= n; i++) {
while (cin >> input && input) {
e[i].push_back(input);
}
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])tarjan(i);
}
for (int i = 1; i <= n; i++) {
for (auto& x : e[i]) {
if (id[i] != id[x]) {
d[id[i]]++;
d2[id[x]]++;
}
}
}
int a = 0,b = 0;
for (int i = 1; i <= c; i++) {
if (d[i] == 0)a++;
if (d2[i] == 0)b++;
}
if (c == 1) cout << 1 << endl << 0 << endl;
else cout << b << endl << max(a, b) << endl;
}
int main() {
slove();
return 0;
}
割点
#include <bits/stdc++.h>
using namespace std;
inline int read(int& x) {
char ch = getchar();
int f = 1; x = 0;
while (ch > '9' || ch < '0') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
//void ReadFile() {
// FILE* stream1;
// freopen_s(&stream1,"in.txt", "r", stdin);
// freopen_s(&stream1,"out.txt", "w", stdout);
//}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return nullptr; }();
const int maxn = 2e4 + 7;
int n, m,low[maxn],dfn[maxn],ans[maxn],tim = 0;
vector<int> e[maxn];
void tarjan(int x, int root) {
low[x] = dfn[x] = ++tim;
int child = 0;
for (auto& y : e[x]) {
if (!dfn[y]) {
tarjan(y, root);
low[x] = min(low[x], low[y]);
if (low[y] >= dfn[x] && x != root) ans[x] = 1;
if (x == root)++child;
}
else low[x] = min(low[x], dfn[y]);
}
//根节点2个以上子树
if (child > 1 && x == root)ans[x] = 1;
}
void slove() {
cin >> n >> m;
int x, y;
for (int i = 1; i <= m; i++) {
cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
for (int i = 1; i <= n; i++)if (!dfn[i])tarjan(i, i);
int cnt = 0;
for (int i = 1; i <= n; i++)if (ans[i])++cnt;
cout << cnt << endl;
for (int i = 1; i <= n; i++) {
if (ans[i])cout << i << " ";
}
cout << endl;
}
int main() {
slove();
return 0;
}
点双连通分量
#include <bits/stdc++.h>
using namespace std;
inline int read(int& x) {
char ch = getchar();
int f = 1; x = 0;
while (ch > '9' || ch < '0') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
//void ReadFile() {
// FILE* stream1;
// freopen_s(&stream1,"in.txt", "r", stdin);
// freopen_s(&stream1,"out.txt", "w", stdout);
//}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return nullptr; }();
const int maxn = 5e5 + 7,maxm = 2e6 + 7;
int n, m, dfn[maxn], low[maxn], num = 0,st[maxm],top = 0,d[maxn],cnt = 0;
vector<int> ans[maxn],e[maxn];
void tarjan(int x) {
dfn[x] = low[x] = ++num;
st[++top] = x;
if (!d[x]) {
ans[cnt++].push_back(x);
return;
}
int flag = 0;
for (auto& y : e[x]) {
if (!dfn[y]) {
tarjan(y);
low[x] = min(low[x], low[y]);
if (low[y] >= dfn[x]) {
int t = 0;
do {
t = st[top--];
ans[cnt].push_back(t);
} while (t != y);
ans[cnt++].push_back(x);
}
}
else low[x] = min(low[x], dfn[y]);
}
}
void slove() {
cin >> n >> m;
int x, y;
for (int i = 1; i <= m; i++) {
cin >> x >> y;
if (x != y) {
e[x].push_back(y);
e[y].push_back(x);
d[x]++, d[y]++;
}
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])tarjan(i);
}
cout << cnt << endl;
for (int i = 0; i < cnt; i++) {
cout << ans[i].size() << " ";
for (auto& nx : ans[i]) {
cout << nx << " ";
}
cout << endl;
}
}
int main() {
slove();
return 0;
}
割边
#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
inline int read(int& x) {
char ch = getchar();
int f = 1; x = 0;
while (ch > '9' || ch < '0') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
//void ReadFile() {
// FILE* stream1;
// freopen_s(&stream1,"in.txt", "r", stdin);
// freopen_s(&stream1,"out.txt", "w", stdout);
//}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return nullptr; }();
const int maxn = 200;
int n,m,dfn[maxn],low[maxn],f[maxn],nTime = 0;
vector<int> p[maxn];
vector<pair<int, int>> ans;
void tarjan(int u, int fa) {
dfn[u] = low[u] = ++nTime;
for (auto& nx : p[u]) {
if (nx == fa)continue;
if (!dfn[nx]) {
f[nx] = u;
tarjan(nx, u);
low[u] = min(low[u], low[nx]);
if (low[nx] > dfn[u])ans.push_back({ min(nx,u),max(nx,u) });
}
else if (nx != f[u])low[u] = min(low[u], dfn[nx]);
}
}
int main()
{
cin >> n >> m;
int a, b;
for (int i = 0; i < m; i++) {
cin >> a >> b;
p[a].push_back(b);
p[b].push_back(a);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i])tarjan(i, -1);
}
sort(ans.begin(), ans.end());
for (int i = 0; i < ans.size(); i++) {
cout << ans[i].first << " " << ans[i].second << endl;
}
return 0;
}
边双连通分量
#include <bits/stdc++.h>
using namespace std;
inline int read(int& x) {
char ch = getchar();
int f = 1; x = 0;
while (ch > '9' || ch < '0') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); }
return x * f;
}
//void ReadFile() {
// FILE* stream1;
// freopen_s(&stream1,"in.txt", "r", stdin);
// freopen_s(&stream1,"out.txt", "w", stdout);
//}
static auto speedup = []() {ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); return nullptr; }();
const int maxn = 5e5 + 7;
int dfn[maxn], low[maxn], nTime = 0,st[maxn],stop = 0,cnt = 0,n,m;
vector<int> ans[maxn];
vector<pair<int, int>> e[maxn];
void tarjan(int x, int fa) {
dfn[x] = low[x] = ++nTime;
st[++stop] = x;
for (auto& nx : e[x]) {
if (nx.second == (fa ^ 1))continue;
int y = nx.first;
if (!dfn[y]) {
tarjan(y, nx.second);
low[x] = min(low[x], low[y]);
}
else low[x] = min(low[x], dfn[y]);
}
if (dfn[x] == low[x]) {
int v;
do {
v = st[stop--];
ans[cnt].push_back(v);
} while (v != x);
cnt++;
}
}
void slove() {
cin >> n >> m;
int a, b;
for (int i = 1; i <= m; i++) {
cin >> a >> b;
e[a].push_back({ b,i << 1 });
e[b].push_back({a,(i << 1) + 1});
}
for (int i = 1; i <= n; i++)if (!dfn[i])tarjan(i, 0);
cout << cnt << endl;
for (int i = 0; i < cnt; i++) {
cout << ans[i].size() << " ";
for (auto& y : ans[i]) {
cout << y << " ";
}
cout << endl;
}
}
int main() {
slove();
return 0;
}