其他分享
首页 > 其他分享> > Equivalent Sets HDU - 3836(tarjan缩点)

Equivalent Sets HDU - 3836(tarjan缩点)

作者:互联网

题意

  一张有向图,需要至少连多少条边使得这个图强联通

思路

  缩点成一张拓扑图,问题就转化成,至少需要加几条边使得这个拓扑图变成一张强联通图。设p为拓扑图入度为0的点的个数,q为出度为0的点的个数,需要加的边数就是max(p,q)。证明略(我不会)。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<stack>
using namespace std;
const int MAX_N = 20010;
const int MAX_M = 50010;
struct edge {
	int v, nxt;
}e[MAX_M];
int n, m;
int dfn[MAX_N], low[MAX_N], timestamp;
int head[MAX_M], cnt = 1;
int id[MAX_N], scc_cnt;
int in_stack[MAX_N];
int din[MAX_N], dout[MAX_N];
stack<int>S;
void init() {
	memset(dfn, 0, sizeof dfn);
	memset(id, 0, sizeof id);
	memset(low, 0, sizeof low);
	memset(head, -1, sizeof head);
	memset(in_stack, 0, sizeof in_stack);
	memset(din, 0, sizeof din);
	memset(dout, 0, sizeof dout);
	scc_cnt = 0, cnt = 1, timestamp = 0;
	while (!S.empty())S.pop();
}
void add(int u, int v) {
	e[cnt].v = v;
	e[cnt].nxt = head[u];
	head[u] = cnt++;
}
void tarjan(int u) {
	dfn[u] = low[u] = ++timestamp;
	S.push(u);
	in_stack[u] = true;
	for (int i = head[u]; ~i; i = e[i].nxt) {
		int v = e[i].v;
		if (!dfn[v]) {
			tarjan(v);
			low[u] = min(low[u], low[v]);
		}
		else if (in_stack[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		++scc_cnt;
		while (1) {
			int y = S.top();
			in_stack[y] = false;
			S.pop();
			id[y] = scc_cnt;
			if (y == u)break;
		}
	}
}
int main() {
	while (scanf("%d%d", &n, &m) != EOF) {
		init();
		for (int i = 1; i <= m; i++) {
			int x, y;
			scanf("%d%d", &x, &y);
			add(x, y);
		}
		for (int i = 1; i <= n; i++) {
			if (!dfn[i])tarjan(i);
		}
		for (int i = 1; i <= n; i++) {
			for (int j = head[i]; ~j; j = e[j].nxt) {
				int v = e[j].v;
				int a = id[i], b = id[v];
				if (a != b) {
					dout[a]++;
					din[b]++;
				}
			}
		}
		int a = 0;
		int b = 0;
		for (int i = 1; i <= scc_cnt; i++) {
			if (!din[i])a++;
			if (!dout[i])b++;
		}
		if (scc_cnt == 1)cout << 0 << endl;
		else
			cout << max(a, b) << endl;
	}
	return 0;
}

标签:缩点,tarjan,int,MAX,Equivalent,memset,cnt,dfn,low
来源: https://blog.csdn.net/qq_43560101/article/details/104842123