Sweety

Practice makes perfect

导航

Critical Links(连通图 桥)

Posted on 2016-05-09 17:03  蓝空  阅读(142)  评论(0编辑  收藏  举报

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=67418#problem/C

求桥裸题:

这个模板好像和KB的还不太一样,有时间研究下

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
const int M = (N << 2);

struct node
{
	int next;
	int to;
//	int id;
}edge[M];

struct BRIDGE
{
	int u;
	int v;
}bridge[M];

int head[N];
int DFN[N];
int low[N];
int st[N];
bool instack[N];
int tot, top, ord, sccnum, cnt;

void init ()
{
	memset (head, -1, sizeof(head));
	memset (DFN, -1, sizeof(DFN));
	memset (low, 0, sizeof(low));
	memset (instack, 0, sizeof(instack));
	tot = top = cnt = sccnum = ord = 0;
}

void addedge (int from, int to)
{
	edge[tot].to = to;
//	edge[tot].id = id;
	edge[tot].next = head[from];
	head[from] = tot++;
}

int cmp (BRIDGE a, BRIDGE b)
{
	if (a.u == b.u)
	{
		return a.v < b.v;
	}
	return a.u < b.u;
}

void tarjan (int u, int fa)
{
	DFN[u] = low[u] = ++ord;
	instack[u] = 1;
	st[top++] = u;
	for (int i = head[u]; ~i; i = edge[i].next)
	{
		int v = edge[i].to;
		if (v == fa)
		{
			continue;
		}
		if (DFN[v] == -1)
		{
			tarjan (v, u);
			low[u] = min (low[v], low[u]);
			if (low[v] > DFN[u])
			{
				bridge[++cnt].u = u;
				bridge[cnt].v = v;
				if (bridge[cnt].u > bridge[cnt].v)
				{
					swap (bridge[cnt].u, bridge[cnt].v);
				}
			}
		}
		else if (instack[v])
		{
			low[u] = min (low[u], DFN[v]);
		}
	}
	if (low[u] == DFN[u])
	{
		++sccnum;
		int v;
		do
		{
			v = st[--top];
			instack[v] = 0;
		}while (u != v);
	}
}

void solve (int n)
{
	for (int i = 1; i <= n; ++i)
	{
		if (DFN[i] == -1)
		{
			tarjan(i, -1);
		}
	}
	sort (bridge + 1, bridge + cnt + 1, cmp);
	printf("%d critical links\n", cnt);
	for (int i = 1; i <= cnt; ++i)
	{
		printf("%d - %d\n", bridge[i].u - 1, bridge[i].v - 1);
	}
	printf("\n");
}

int main()
{
	int n;
	int u, v;
	int num;
	while (~scanf("%d", &n))
	{
		if (n == 0)
		{
			printf("0 critical links\n\n");
			continue;
		}
		init();
		for (int i = 1; i <= n; ++i)
		{
			scanf("%d", &u);
			++u;
			getchar();
			getchar();
			scanf("%d", &num);
			getchar();
			while (num--)
			{
				scanf("%d", &v);
				++v;
				addedge (u, v);
			}
		}
		solve (n);
	}
	return 0;
}