POJ-1236Network of Schools

来源:互联网 发布:js替换标签 编辑:程序博客网 时间:2024/06/13 21:49
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.

 题目大意:给你一个用有向边连接的图,然后问你两个问题:(1)从任意某些点出发要求遍历整张图。要求点得数量最少。

(2)在图中加一些边,使得从图中所有点出发都能遍历整张图。

题意分析:考得是强连通分量+缩点,把强连通分量缩成点后得到一张新得图,然后求图中各个点的是否存在入度和出度,很

显然入度等于0的点的数量就是答案1;而答案2就是入度等于0的点的数量和出度等于0的点的数量的最大值,因为问题2就是要把整张图变化成强连通图。

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<set>#include<vector>#include<iomanip>#include<queue>#include<map>#include<stack>using namespace std;typedef long long LL;typedef unsigned long long ULL;const int INF=0x3f3f3f3f,maxn=105;int N,scc_cnt;int sccno[maxn],pre[maxn],dfs_clock,low[maxn],in[maxn],out[maxn];stack<int> S;vector<int> ax[maxn];void init(){    scc_cnt=dfs_clock=0;    memset(pre,0,sizeof(pre));    memset(sccno,0,sizeof(sccno));}void dfs(int u){    pre[u]=low[u]=++dfs_clock;    S.push(u);    for(int i=0;i<ax[u].size();i++)    {        int v=ax[u][i];        if(!pre[v])        {            dfs(v);            low[u]=min(low[u],low[v]);        }        else if(!sccno[v])            low[u]=min(low[u],pre[v]);    }    if(pre[u]==low[u])    {        scc_cnt++;        while(true)        {            int x=S.top();            S.pop();            sccno[x]=scc_cnt;            if(x==u)                break;        }    }}int main(){   scanf("%d",&N);   init();   int ans1=0,ans2=0;   for(int i=1;i<=N;i++)   {       int a;       while(scanf("%d",&a)&&a)          ax[i].push_back(a);   }   for(int i=1;i<=N;i++)       if(!pre[i])           dfs(i);   for(int i=1;i<=scc_cnt;i++)in[i]=out[i]=0;   for(int u=1;u<=N;u++)   {       for(int i=0;i<ax[u].size();i++)       {           int v=ax[u][i];           if(sccno[u]!=sccno[v])               in[sccno[v]]=out[sccno[u]]=1;       }   }   int a=0,b=0;   for(int i=1;i<=scc_cnt;i++)   {       if(!in[i])a++;       if(!out[i])b++;   }   ans1=a;   ans2=max(a,b);   if(scc_cnt==1)    ans2=0;   printf("%d\n%d\n",ans1,ans2);   return 0;}


原创粉丝点击