Tarjan模板题求割点,桥

模板题:Tarjan算法求割点,桥

  1.  UVA - 796 Critical Links Tarjan求割点个数
题目链接: Vjudge 
题意: 给定N个顶点若干条边, 求割点个数。
思路:模板题。套用kuangbin大牛的 Tarjan 模板。
#include 
using namespace std;

#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
#define fst             first
#define snd             second

const int MAXN = 100 + 5;
const int MAXM = MAXN * MAXN * 2 + 5;
struct Edge {
	int v, next;
	Edge() {}
	Edge(int v, int next) : v(v), next(next) {}
} edge[MAXM];
int head[MAXN], tot;
int low[MAXN], dfn[MAXN], add_block[MAXN];
int Index;
int N, res;
char buf[300];

void add_edge(int u, int v) {
	edge[tot] = Edge(v, head[u]);
	head[u] = tot++;
}
void Tarjan(int u, int pre) {
	int v, son = 0;
	low[u] = dfn[u] = ++Index;
	for (int i = head[u]; ~i; i = edge[i].next) {
		v = edge[i].v;
		if (v == pre) continue;
		if (!dfn[v]) {
			son ++;
			Tarjan(v, u);
			low[u] = min(low[u], low[v]);
			if (u != pre && low[v] >= dfn[u]) {
				add_block[u] ++;
			}
		} else {
			low[u] = min(low[u], dfn[v]);
		}
		if (u == pre) {
			add_block[u] = son - 1;
		}
	}
}
void init() {
	tot = 0;
	memset(head, -1, sizeof(head));
	memset(dfn, 0, sizeof(dfn));
	memset(add_block, 0, sizeof(add_block));
	Index = res = 0;
}
int main() {
#ifndef ONLINE_JUDGE
	FIN;
#endif // ONLINE_JUDGE
	while (~scanf("%d\n", &N) && N) {
		int u, v;
		init();
		while (gets(buf) != NULL) {
			if (buf[0] == '0') break;
			char* p = strtok(buf, " ");
			sscanf(p, "%d", &u);
			p = strtok(NULL, " ");
			while (p) {
				sscanf(p, "%d", &v);
				p = strtok(NULL, " ");
				add_edge(u, v);
				add_edge(v, u);
			}
		}
		for (int i = 1; i <= N; i++) {
			if (!dfn[i]) Tarjan(i, i);
		}
		for (int i = 1; i <= N; i++) {
			if (add_block[i]) res ++;
		}
		printf("%d\n", res);
	}
	return 0;
}

  1. UVA - 796 Critical Links Tarjan求桥

题目链接: Vjudge
题意:给定若干顶点,和若干条边组成的无向图,求桥的个数,并且依次打印出每条桥的两个端点。顶点个数题目没有给出,测试在100个顶点以内吧。注意每组数据输出空行。结果保存在set中,去重。
#include 
using namespace std;

#define FIN             freopen("input.txt","r",stdin)
#define FOUT            freopen("output.txt","w",stdout)
#define fst             first
#define snd             second
typedef pair	PII;

const int MAXN = 100 + 5;
const int MAXM = MAXN * MAXN * 2 + 5;

struct Edge {
	int v, next;
	bool cut;
	Edge() {}
	Edge(int v, int next, bool cut) : v(v), next(next), cut(cut) {}
} edge[MAXM];
int head[MAXN], tot;
int low[MAXN], dfn[MAXN];
int Index, top;
int bridge;
int N, M;
set res;

void add_edge(int u, int v) {
	edge[tot] = Edge(v, head[u], false);
	head[u] = tot++;
}
void Tarjan(int u, int pre) {
	int v;
	low[u] = dfn[u] = ++Index;
	for (int i = head[u]; ~i; i = edge[i].next) {
		v = edge[i].v;
		if (v == pre) continue;
		if (!dfn[v]) {
			Tarjan(v, u);
			low[u] = min(low[u], low[v]);
			if (low[v] > dfn[u]) {
				bridge++;
				edge[i].cut = true;
				edge[i ^ 1].cut = true;
				res.insert(make_pair(min(u, v), max(u, v)));
			}
		} else if (low[u] > dfn[v]) {
			low[u] = dfn[v];
		}
	}
}
void init() {
	tot = Index = 0;
	bridge = 0;
	memset(dfn, 0, sizeof(dfn));
	memset(head, -1, sizeof(head));
	res.clear();
}
int main() {
#ifndef ONLINE_JUDGE
	FIN;
#endif // ONLINE_JUDGE
	int u, v;
	while (~scanf("%d", &N)) {
		init();
		for (int i = 0; i < N; i++) {
			scanf("%d (%d)", &u, &M);
			while (M --) {
				scanf("%d", &v);
				add_edge(u, v);
				add_edge(v, u);
			}
		}
		for (int i = 0; i < N; i++) {
			if (!dfn[i]) Tarjan(i, i);
		}
		printf("%d critical links\n", bridge);
		for (set::iterator iter = res.begin(); iter != res.end(); iter++) {
			printf("%d - %d\n", (*iter).fst, (*iter).snd);
		}
		puts("");
	}
	return 0;
}

你可能感兴趣的:(ACM____图,论)