【POJ 1236】Network of Schools(tarjan算法)
2016-06-18 08:04
351 查看
Network of Schools
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 IOI 1996 |
[Discuss]
Home Page
Go
Back
To top
[题意][有N个学校...每个学校可能向几个学校进行数据传输(单向的)问..至少需要把一个文件给几个学校可以使给的N个学校都收到文件...再问在加几个通信线路可以使各个学校之间都能直接或间接的传递文件]
【题解】【一个强连通分量里的所有点可以互相传输,那么这道题实际上就是在求当前图中有几个强连通分量,第二问是问还需再加入几条边,也就是说还需要几条边把剩下的点连起来。因为一个强连通分量必然不需要考虑,所以考虑把每个强连通分量缩成一个点来处理】
【求强连通分量要用到tarjan算法】
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100500],nxt[100500],p[110],tot;//next数组存有向图 int dft[110],dis[110],root,cnt;//dst表示dfs到当前点的时间,dis表示当前点可到达的点中时间最小的 int in[110],out[110],f[110],n;//点的入度和出度,f是缩点后的每个点的序号 int d[110],top;//栈 bool vis[110];//记录每个元素是否在栈中 inline void add(int x,int y) { tot++; a[tot]=y; nxt[tot]=p[x]; p[x]=tot; } void tarjan(int u) { dft[u]=dis[u]=++cnt; d[++top]=u; vis[u]=1; int v=p[u]; while(v>=0) { if(!dft[a[v]]) { tarjan(a[v]); dis[u]=min(dis[u],dis[a[v]]); } else if(vis[a[v]]&&dis[u]>dft[a[v]]) dis[u]=dft[a[v]]; v=nxt[v]; } int b=a[p[u]]; if(dft[u]==dis[u])//说明找到一个强连通分量 { ++root;//缩点 do{ b=d[top--]; vis[b]=false; f[b]=root; }while(u!=b);//把当前强连通分量里包含的所有点缩成一个点来代替 } return; }//查找强连通分量 void solve() { root=top=cnt=0; memset(dft,0,sizeof(dft)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;++i) if(!dft[i]) tarjan(i); return; }//dfs找所有的强连通分量,每次从一个没有搜索过的点开始 void count() { memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); for(int i=1;i<=n;++i) { int u=p[i]; while(u>=0) { if(f[i]!=f[a[u]]) out[f[i]]++,in[f[a[u]]]--; u=nxt[u]; } } return; }//缩点后,看还有几个点不属于强连通分量,则统计入度和出度,以便于后面计算要新加几条边 int main() { int i,j; while((scanf("%d",&n)==1)&&n) { tot=0; memset(nxt,-1,sizeof(nxt)); memset(p,-1,sizeof(p)); int b; for(i=1;i<=n;++i) while((scanf("%d",&b)==1)&&b) add(i,b); solve(); if(root==1) {printf("1\n0\n"); continue;}//如果缩完后就剩下一个点,即不需要再添边,直接输出即可 count(); int inr=0,outr=0; for(i=1;i<=root;++i) { if(!in[i]) inr++; if(!out[i]) outr++; } //看缩点后有几个单独的点,就要新加几条边 printf("%d\n%d\n",inr,max(inr,outr)); } return 0; }(Tarjan算法见上一篇博文)
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法