proof of the problem
Network of schools (POJ 1236) A number of schools is connected to A computer network. Agreements has been developed among those Schools:each School maintains a list of schools to which it distributes Softwa Re (the "Receiving schools"). Note that if B was in the distribution list of school A, then a does not necessarily appear in the list of school B
You is to write a program this computes the minimal number of schools that must receive a copy of the new software in Ord Er for the software to reach all schools in the network according to the agreement (Subtask A). As a further task, we want to ensure is sending the copy of new software to an arbitrary school, this software would r Each of the schools in the network. To achieve this goal we are having to extend the lists of receivers by new members. Compute the minimal number of extensions that has to is made so this whatever school we send the new software to, it'll Reach all other schools (Subtask B). One extension means introducing one new member into the list of receivers of one school.some little proof.
By the topic, we can establish a graph between schools, we can know that the points between the strong connected components can reach each other. So we use the Tarjan algorithm to calculate all the strong connected components. If this graph is a strong connected graph, then we can know that just put the software in a school. Let's look at the case of non-strong connectivity graphs.
We shrink the strongly connected component to a single point, then there is still a possibility that one-way connections can be made between these points. But it is never possible to connect in two directions.
The first question: at least how many schools we need to put the software in. We calculate the penetration of all the strongly connected components, and if a strong connected component has a degree of 0, we need to place the software within the strongly connected component. It is easy to know that each strong connected component with a degree greater than 0 will be weakly communicated with a strong connected component with a penetration of 0. So all we need to do is calculate the points in the graph after the indentation to be 0.
The second question: How many sides do we need to add to make this graph a strong connected graph?
Proof: In a forward-connected graph, the graph is a strongly connected graph when and only if all points are not in and out of the 0
necessity: Obviously if figure G is a strongly connected graph, then all points are not in and out of 0
Adequacy: We can prove a stronger conclusion: The diagram now contains a Euler sub-graph. The definition of Eulerian graph in the
graph is: For all points there is deg+ (v) = deg-(v)
and at this point, we have a bit more in and out than 1, then delete the appropriate points, you will be bound to get a connection all nodes implementation code
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <
Stack> using namespace std;
const int MAXN = 105;
int dfn[maxn],low[maxn],n;
int grid[maxn][maxn],state[maxn],cur,num;
int OUTDEG[MAXN],INDEG[MAXN],BELONG[MAXN];
stack<int>s;
void init () {cur = 1; num = 0;
memset (dfn,0,sizeof (DFN));
memset (low,0,sizeof (Low));
memset (state,0,sizeof (state));
memset (grid,0,sizeof (grid));
memset (indeg,0,sizeof (indeg));
memset (outdeg,0,sizeof (outdeg));
Memset (Belong,0,sizeof (belong));
} void Dfs (int index,int time) {Dfn[index] = low[index] = time;
State[index] = 1;
S.push (index);
int i;
for (i=1;i<=n;i++) {if (grid[index][i] = = 1) {if (!state[i]) {Dfs (i,++cur);
Low[index] = min (low[index],low[i]);
} else if (state[i] = = 1) low[index] = min (low[index],low[i]); }} if (Dfn[index] == Low[index]) {num++;
int temp;
while (1) {temp = S.top ();
S.pop ();
printf ("%d", temp);
BELONG[TEMP] = num;
State[temp] = 2;
if (temp = = index) break;
}}} void Solve () {int i,j,ans1=0,ans2=0;
for (i=1;i<=n;i++) {if (!state[i]) {Dfs (i,cur); }} for (i=1;i<=n;i++) {for (j=1;j<=n;j++) {if (grid[i][j] = = 1 && belong[i]! = Bel
Ong[j]) {indeg[belong[j]]++;
outdeg[belong[i]]++;
}}} for (i=1;i<=num;i++) {if (!indeg[i]) ans1++;
if (!outdeg[i]) ans2++;
} if (num = = 1) printf ("1\n0\n");
else printf ("%d\n%d\n", Ans1,max (ANS1,ANS2));
Return
} int main () {freopen ("input", "R", stdin);
int i,temp;
Init ();
scanf ("%d", &n);
for (i=1;i<=n;i++) {while (1) {scanf ("%d", &temp); if (!temp) break;
Grid[i][temp] = 1;
}} Solve ();
}