HDOJ 5409 CRB and Graph

从n开始做tarjan,如果一条边不是桥,那么就输出0 0,否则求子树的最大编号。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

#define mp(x, y) make_pair(x, y)
const int maxn = 100005;
const int maxm = 200005;

struct Edge
{
	int v, next;
	Edge(int v = 0, int next = 0) : v(v), next(next) {}
}E[maxm];

pair<int, int> res[maxn];
int H[maxn], cntE;
int dfn[maxn];
int low[maxn];
int mx[maxn];
int n, m, dfs_clock;

void addedges(int u, int v)
{
	E[cntE] = Edge(v, H[u]);
	H[u] = cntE++;
	E[cntE] = Edge(u, H[v]);
	H[v] = cntE++;
}

void init()
{
	cntE = dfs_clock = 0;
	memset(dfn, 0, sizeof dfn);
	memset(H, -1, sizeof H);
}

void tarjan(int u, int fa)
{
	mx[u] = u;
	dfn[u] = low[u] = ++dfs_clock;

	for(int e = H[u]; ~e; e = E[e].next) if(E[e].v != fa) {
		int v = E[e].v;
		if(!dfn[v]) {
			tarjan(v, u);
			low[u] = min(low[u], low[v]);
		}
		else low[u] = min(low[u], dfn[v]);
	}

	for(int e = H[u]; ~e; e = E[e].next) if(E[e].v != fa) {
		int v = E[e].v;
		mx[u] = max(mx[u], mx[v]);
		if(low[v] > dfn[u]) res[e / 2] = mp(mx[v], mx[v]+1);
		else res[e / 2] = mp(0, 0);
	}
}

void work()
{
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++) {
		int u, v;
		scanf("%d%d", &u, &v);
		addedges(u, v);
	}
	
	
	tarjan(n, n);

	for(int i = 0; i < m; i++) printf("%d %d\n", res[i].first, res[i].second);
}

int main()
{
	int _;
	scanf("%d", &_);
	while(_--) {
		init();
		work();
	}
	
	return 0;
}


你可能感兴趣的:(桥)