POJ 1236 (strongly connected components)

Topic Link  http://poj.org/problem?id=1236

Translate what topic it ,,,,

Roughly meaning is, there are n school, now want to pass a software n school, if the school is willing to support A B school, then to the A, A will give B, but A support B but B does not necessarily support A ( there warning directed graph ), what is required of it, at least to the number of schools can give to all schools, plus at least a few support relationship, can make to any one school can be delivered to the entire school.

Ideas:

The first question it, first of all within the same strongly connected components of a school can give freely, so it can be viewed as a strongly connected component of a point processing ( reduced point later), point reduction, re-built map, a point represents a strongly connected component is not within a strongly connected component, if there is a point a to reach a point in the B, then the equivalent of two connecting edges have strongly connected components a -> B, for such a relationship, we They found that, as long as the a, a will give B, that is to say, for such a chain, just give up after the first of those things have been, first how it represents? ? ? For A -> B -> C, discovery, B and C have the degree, that is to say B and C will have passed them to school, do not have control, for A is concerned, it is no penetration, but also That is, if you do not give him, he can not there will be. So long as the statistics into a degree of zero point number can be.

For the second problem, ahhhh, I would like a little while it corresponds to the point of the whole graph, strongly connected components into a added after several sides, points inside the strongly connected components each meet certain point of at least a penetration and a degree out, then there is no penetration of the drawings, the degree of the gradual feed, a point no degrees of fill that can form a strongly connected components. To the least, it is certainly self-sufficient, that is to the point and the degree of 0 is 0 even point edge, for example, now has n is 0 points out, there are n enter is 0, these point even the n a is 0 points, respectively, to the n a is 0 side, so that completion of the degree and the degree of 0 point, a different number of points if the out-degree, and the degree of 0, it is assumed connected to the point with m is 0, a is 0 there are n, n> m, but also make sure the point is first selected from the n th and m is 0 the edges, points out the remaining nm is 0, only these nm points to the first n make up points connected to the degree of edge on the line, if the degree is greater than a degree, the original out of point 0 of the multi-degree point 0 connected on the line side, so the answer is max (n, m)

In particular, if there is only one strongly connected component, and the second would not have statistics, direct is 0 on it.

/**
 * Author : correct
 */
#include <iostream>
#include <cstdio>
#include <cstring>
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 10100;
int head[N], nex[N], to[N], cnt;
void add(int a, int b){
	++cnt;
	to[cnt] = b;
	nex[cnt] = head[a];
	head[a] = cnt;
}
int n;
int dfn[110], low[110];
bool vis[110];
int block[110];// 记录属于哪一个强连通分量
int st[110], top;
int num, q;
void pre_work(){
	mem(head, -1);
	mem(nex, - 1);
	cnt = 0;
	num = 0;
	mem(dfn, 0);
	mem(low, 0);
	mem(vis, 0);
	top = 0;
	q = 0;
	mem(block, 0);
}
void tarjan(int x){
	dfn[x] = low[x] = ++num;
	st[++top] = x;
	vis[x] = 1;
	for (int i = head[x]; ~i; i = nex[i]){
		int y = to[i];
		if (dfn[y] == 0){
			tarjan(y);
			low[x] = min(low[x], low[y]);
		}
		else if (vis[y])low[x] = min(low[x], dfn[y]);
	}
	if (low[x] == dfn[x]){
		++q;
		while (1){
			int t = st[top--];
			vis[t] = 0;
			block[t] = q;
			if (t == x)break;
		}
	}
}
bool c[110];
bool out[110];
int main(){
	// 1.统计入读为0的点的个数
	// 2.出度为0和入度为0点数的最大值,特别地,只有一个强连通分量的时候是0
	pre_work();
	ios::sync_with_stdio(false);
	cin >> n;
	for (int i = 1; i <= n; i++){
		int x;
		while (cin >> x && x){
			add(i, x);
		}
	}
	for (int i = 1; i <= n; i++){
		if (dfn[i] == 0){
			tarjan(i);
		}
	}
	mem(c, 0);
	mem(out, 0);
	for (int i = 1; i <= n; i++){
		for (int j = head[i]; ~j; j = nex[j]){
			int y = to[j];
			if (block[i] != block[y]){
				c[block[y]] = 1;// 入度
				out[block[i]] = 1;// 出度
			}
		}
	}
	int ans = 0;
	int chu, ru;
	chu = 0;
	ru = 0;
	for (int i = 1; i <= q; i++){
		if (!c[i])++ans;
		if (!c[i])ru++;
		if (!out[i])chu++;
	}
	cout << ans << "\n";
	cout << (q == 1 ? 0 : max(chu, ru)) << "\n";
	return 0;
}

 

Published 204 original articles · won praise 13 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_43701790/article/details/104795964