割点与割边

强联通

受欢迎的牛

#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;
}

割点

P3388 【模板】割点(割顶)

#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;
}

点双连通分量

P8435 【模板】点双连通分量

#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;
}

割边

P1656 炸铁路

#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;
}

边双连通分量

P8436 【模板】边双连通分量

#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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值