Description
Input
Output
Sample Input
5
2 4 3 0
4 5 0
0
0
1 0
Sample Output
1
2
题意:有n个学校,学校之间可以传递信息,为单向传递。
问题一:至少要向几个学校传递原始信息,才能保证所有学校都能收到信息。
<span style="font-size:18px;">#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <string> #include <algorithm> #include <queue> #include <stack> using namespace std; const double PI = acos(-1.0); const double e = 2.718281828459; const double eps = 1e-8; const int MAXN = 110; int n; struct Edge { int v; int w; int next; } edge[MAXN*MAXN]; struct shrink_point { int in; int out; int num; } sp[MAXN]; int head[MAXN]; int instack[MAXN]; int scc[MAXN]; int LOW[MAXN]; int DFN[MAXN]; stack<int>Q; int Index, edge_cnt, scc_cnt; void addedge(int u, int v) { edge[edge_cnt].v = v; edge[edge_cnt].next = head[u]; head[u] = edge_cnt++; } void Tarjan(int u) { LOW[u] = DFN[u] = ++Index; instack[u] = 1; Q.push(u); for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(!DFN[v]) { Tarjan(v); if(LOW[u] > LOW[v]) LOW[u] = LOW[v]; } else if(instack[v] && LOW[u]>DFN[v]) LOW[u] = DFN[v]; } if(LOW[u] == DFN[u]) { int j; scc_cnt++; do { j = Q.top(); Q.pop(); instack[j] = 0; scc[j] = scc_cnt; sp[scc_cnt].num++; } while(j != u); } } void solve() { memset(LOW, 0, sizeof(LOW)); memset(DFN, 0, sizeof(DFN)); memset(instack, 0, sizeof(instack)); memset(sp, 0, sizeof(sp)); while(!Q.empty()) Q.pop(); Index = scc_cnt = 0; for(int i = 1; i <= n; i++) if(!DFN[i]) Tarjan(i); for(int i = 1; i <= n; i++) for(int k = head[i]; k != -1; k = edge[k].next) { int j = edge[k].v; if(scc[i] != scc[j]) { sp[scc[i]].out++; sp[scc[j]].in++; } } if(scc_cnt == 1) { printf("%d\n%d\n", 1, 0); return; } int num1 = 0; int num2 = 0; for(int i = 1; i <= scc_cnt; i++) { if(sp[i].out == 0) num1++; if(sp[i].in == 0) num2++; } //printf("%d %d\n", num1, num2); printf("%d\n%d\n", num2, max(num1, num2)); } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); while(cin>>n) { int v; edge_cnt = 0; memset(head, -1, sizeof(head)); memset(edge, 0, sizeof(edge)); for(int i = 1; i <= n; i++) { while(cin>>v&&v) { addedge(i, v); } } // for(int i = 1; i <= n; i++) // { // printf("%d", i); // for(int k = head[i]; k != -1; k = edge[k].next) // { // printf(" %d", edge[k].v); // } // printf("\n"); // } solve(); } return 0; } </span>
POJ 1236 - Network of Schools(强连通分量)
原文地址:http://blog.csdn.net/u014028317/article/details/45605371