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