Information Transmission-2(2019第十二屆ICPC-ACM河南省賽-G-強連通分量)

Information Transmission-2(2019第十二屆ICPC-ACM河南省賽-G-強連通分量)

看到這題第一感覺是驚喜,因爲作爲新生遇到自己學過的算法題不容易。但是等我想上手敲的時候卻無從下手!!不知不覺連不久前剛刷過的專題都手生了。。。

學的東西多了,複習就變成了一件大事……

題目描述

Information plays a very important role in people’s social life. For example, scientific research must not only obtain the results of others 'research in time, but also publish and inform others of the results of their own research in time. Only through this exchange of information can we continue to develop. Network communication is based on computer communication network for information transmission, exchange and utilization.

There are n base points and there is a certain transfer relationship between them., the information can be transmitted from point A to point B, and point B to point C, and so on. Now there is a massage to be broadcasted , at least which base points to be sent the message first, so that all the base points can be received?

輸入

The first line of the input contains one integer TT, which is the number of test cases (1<=T<=8)(1<=T<=8). Each test case specify:
* Line 1: n(2n100)n (2 ≤ n ≤ 100)
*Line 2~n+1: each line contains a 01 string of length n .
ie:if the sixth column in the third row is 11, it means that the third base point can pass the message to the sixth base point.

輸出

For each test case generate a single line: minimum number of base that the massage must be sent first, so that all the basis points can be received.

樣例輸入

2
3
010
001
000
6
010000
001001
000100
010000
001000
000000

樣例輸出

1
2

題意

有一個好消息要傳給nn個人,但這些人不是彼此都有通信的,只有一部分人能傳話給別人(有向圖),告訴你都有誰可以傳給誰,問你最少要通知幾個人能使大家都知道這個消息(強連通)。

輸入格式是加入a[i][j]a[i][j]是1,那麼 ii 就可以傳話給 jj
否則就不能。

代碼

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstdio>
#include <stack>
#include <string.h>
#define maxn 10010
#define inf 0x3f3f3f3f
#define _for(i, a) for(int i = 0; i < (a); i++)
#define _rep(i, a, b) for(int i = (a); i <= (b); i++)
using namespace std;
struct edge {
	int v, next, u, id;
}G[2 * maxn];
int head[maxn], cnt;
int n, m;
int a[maxn];
int scccnt, sccno[maxn];
int dfn[maxn], low[maxn];
int tclock;
stack<int> q;
int ans, num;
int indegree[maxn];
void init() {
	memset(head, -1, sizeof(head));
	memset(dfn, 0, sizeof(dfn));
	memset(low, 0, sizeof(low));
	memset(sccno, 0, sizeof(sccno));
	scccnt = tclock = 0;
	memset(indegree, 0, sizeof(indegree));
	cnt = 0;
}
void add_edge(int u, int v) {
	G[cnt].u = u;
	G[cnt].v = v;
	G[cnt].next = head[u];
	G[cnt].id = cnt;
	head[u] = cnt++;
}
void read() {
	scanf("%d", &n);
	_rep(i, 1, n) {
		_rep(j, 1, n) {
			int x;
			scanf("%1d", &x);
			if (x) {
				add_edge(i, j);
			}
		}
	}
}
void tarjin(int u) {
	dfn[u] = low[u] = ++tclock;
	q.push(u);
	for (int i = head[u]; i != -1; i = G[i].next) {
		int v = G[i].v;
		if (!dfn[v]) {
			tarjin(v);
			low[u] = min(low[u], low[v]);
		}
		else if (!sccno[v]) {
			low[u] = min(low[u], dfn[v]);
		}
	}
	if (dfn[u] == low[u]) {
		scccnt++;
		int v = -1;
		while (v != u) {
			v = q.top();
			q.pop();
			sccno[v] = scccnt;
		}
	}
}
void sol() {
	ans = num = 0;
	_rep(i, 1, n) {
		if (!dfn[i]) {
			tarjin(i);
		}
	}
	for (int i = 0; i < cnt; i++) {
		int u = G[i].u, v = G[i].v;
		if (sccno[u] != sccno[v]) {
			indegree[sccno[v]]++;
		}
	}
	_rep(i, 1, scccnt) {
		if (indegree[i] == 0) {
			ans++;
			num++;
		}
	}
}
int main() {
	int T;
	cin >> T;
	while (T--) {
		init();
		read();
		sol();
		printf("%d\n", num);
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章