Tarjan模板题求割点,桥

来源:互联网 发布:大数据挖掘工程师招聘 编辑:程序博客网 时间:2024/06/18 14:48

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

  1.  UVA - 796 Critical Links Tarjan求割点个数

题目链接:Vjudge 
题意: 给定N个顶点若干条边, 求割点个数。
思路:模板题。套用kuangbin大牛的 Tarjan 模板。
#include <bits/stdc++.h>using namespace std;#define FIN             freopen("input.txt","r",stdin)#define FOUT            freopen("output.txt","w",stdout)#define fst             first#define snd             secondconst 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_JUDGEFIN;#endif // ONLINE_JUDGEwhile (~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 <bits/stdc++.h>using namespace std;#define FIN             freopen("input.txt","r",stdin)#define FOUT            freopen("output.txt","w",stdout)#define fst             first#define snd             secondtypedef pair<int, int>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<PII> 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_JUDGEFIN;#endif // ONLINE_JUDGEint 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<PII>::iterator iter = res.begin(); iter != res.end(); iter++) {printf("%d - %d\n", (*iter).fst, (*iter).snd);}puts("");}return 0;}

1 0
原创粉丝点击