POJ 1236 有向图的连通分量

                                                                                              Network of Schools











Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 9604Accepted: 3820

Description


A number of schools are connected to a computer
network. Agreements have been developed among those schools: each school
maintains a list of schools to which it distributes software (the “receiving
schools”). Note that if B is in the distribution list of school A, then A does
not necessarily appear in the list of school B
You are to write a program
that computes the minimal number of schools that must receive a copy of the new
software in order for the software to reach all schools in the network according
to the agreement (Subtask A). As a further task, we want to ensure that by
sending the copy of new software to an arbitrary school, this software will
reach all schools in the network. To achieve this goal we may have to extend the
lists of receivers by new members. Compute the minimal number of extensions that
have to be made so that whatever school we send the new software to, it will
reach all other schools (Subtask B). One extension means introducing one new
member into the list of receivers of one school.

Input


The first line contains an integer N: the number of
schools in the network (2 <= N <= 100). The schools are identified by the
first N positive integers. Each of the next N lines describes a list of
receivers. The line i+1 contains the identifiers of the receivers of school i.
Each list ends with a 0. An empty list contains a 0 alone in the line.

Output


Your program should write two lines to the standard
output. The first line should contain one positive integer: the solution of
subtask A. The second line should contain the solution of subtask B.

Sample Input

5
2 4 3 0
4 5 0
0
0
1 0

Sample Output

1
2

Source

解题思路:第一问就是找入读为0的点,第二问,假如只有一个连通分量,则无需添加,否则取入度和出度的最大值。

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110;
const int maxm=110*110;
struct Edge{int to,next;}edge[maxm];
int low[maxn],dfn[maxn],stack[maxn],belong[maxn],in[maxn],head[maxn];
bool instack[maxn];
int top,scc,tol,indexx;
void add(int u,int v)
{
     edge[tol].next=head[u];
     edge[tol].to=v;
     head[u]=tol++;
}
void tarjin(int u)
{
       int v;
       low[u]=dfn[u]=++indexx;
       stack[top++]=u;
       instack[u]=1;
       for(int i=head[u];i!=-1;i=edge[i].next)
       {
              v=edge[i].to;
              if(!dfn[v])
              {
                     tarjin(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])
       {
              scc++;
              do
              {
                     v=stack[--top];
                     belong[v]=scc;
                     instack[v]=0;
              }while(v!=u);
       }
}
int out[200];
void solve(int n)
{
       int v,u,i;
       memset(instack,0,sizeof(instack));
       memset(dfn,0,sizeof(dfn));
       top=scc=indexx=0;
       for(i=1;i<=n;i++)if(!dfn[i])tarjin(i);
       if(scc==1){puts("1\n0");return;}
       memset(in,0,sizeof(in));
       memset(out,0,sizeof(out));
       for(u=1;u<=n;u++)
       {
              for(i=head[u];i!=-1;i=edge[i].next)
              {
                     v=edge[i].to;
                     if(belong[u]!=belong[v])
                     {
                             in[belong[v]]++;
                             out[belong[u]]++;
                     }
              }
       }
       int ans1=0,ans2=0;
       for(i=1;i<=scc;i++)
       {
               if(in[i]==0)ans1++;
               if(out[i]==0)ans2++;
       }
       printf("%d\n%d\n",ans1,max(ans1,ans2));
}
int main()
{
       int i,j,k,m,n;
       while(~scanf("%d",&n))
       {
              memset(head,-1,sizeof(head));
              tol=0;
              for(i=1;i<=n;i++)
                     while(~scanf("%d",&j)&&j)add(i,j);
              solve(n);
       }
       return 0;
}

 

posted @ 2013-09-01 09:09  线性无关  阅读(137)  评论(0)    收藏  举报