POJ 1236 Network of Schools(tarjan求强连通分量+思维)

题目链接:http://poj.org/problem?id=1236

题目大意:

给你一个网络(有向图),有两个任务:
①求出至少同时需要几份副本可以使得整个网络都获得副本
②至少添加多少信息表(有向边)使得副本传到任一点,都可以使得整个网络都获得副本

解题思路:

即给定一个有向图,求:

①至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点

②至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点
缩点后,分别求出出度入度为0的点数为sum1,sum2,
问题①的答案就为sum2;
问题②的答案为max(sum1,sum2)(即使得所有点的出度入度都大于0)。
注意,只有一个点时,不需要添加边,答案为1,0。

代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stack>
 6 #include<vector>
 7 using namespace std;
 8 const int N=105;
 9
10 int n,cnt,num;                            //cnt为当前dfs序,num为缩点编号
11 int low[N],dfn[N],fa[N],indeg[N],outdeg[N];//dfn为dfs序,low为节点能够通过返回的最早的祖先(注意这里跟求割边割点里的low不同)
12 vector<int>v[N];                           //fa为节点所属的强联通分量的编号.indeg和outdeg为缩点的入度、出度
13 stack<int>sk;
14
15 void init(){
16     cnt=num=0;
17     for(int i=1;i<=n;i++){
18         v[i].clear();
19     }
20     memset(fa,0,sizeof(fa));
21     memset(low,0,sizeof(low));
22     memset(dfn,0,sizeof(dfn));
23     memset(indeg,0,sizeof(indeg));
24     memset(outdeg,0,sizeof(outdeg));
25 }
26
27 //求强联通分量
28 void tarjan(int u){
29     low[u]=dfn[u]=++cnt;
30     sk.push(u);
31     for(int i=0;i<v[u].size();i++){
32         int t=v[u][i];
33         if(!dfn[t]){                                //未被访问
34             tarjan(t);
35             low[u]=min(low[u],low[t]);
36         }
37         else if(!fa[t]) low[u]=min(low[u],dfn[t]); //被访问过且在栈中
38     }
39     if(low[u]==dfn[u]){
40         num++;
41         while(!sk.empty()){
42             int t=sk.top();
43             sk.pop();
44             fa[t]=num;
45             if(t==u) break;
46         }
47     }
48 }
49
50 int main(){
51     while(~scanf("%d",&n)){
52         init();
53         for(int i=1;i<=n;i++){
54             int x;
55             while(~scanf("%d",&x)&&x) v[i].push_back(x);
56         }
57         for(int i=1;i<=n;i++){              //遍历所有点
58             if(!dfn[i]) tarjan(i);
59         }
60         for(int i=1;i<=n;i++){              //缩点,并求出相应的出度入度是否为0(注意不是求出入度)
61             for(int j=0;j<v[i].size();j++){
62                 int t=v[i][j];
63                 if(fa[t]!=fa[i]){
64                     outdeg[fa[i]]=1;
65                     indeg[fa[t]]=1;
66                 }
67             }
68         }
69         int sum1=0,sum2=0;
70         for(int i=1;i<=num;i++){
71             if(outdeg[i]==0)
72                 sum1++;
73             if(indeg[i]==0)
74                 sum2++;
75         }
76         if(num==1)                          //只有一个点时要特判
77             puts("1\n0");
78         else printf("%d\n%d\n",sum2,max(sum1,sum2));
79     }
80     return 0;
81 }

原文地址:https://www.cnblogs.com/fu3638/p/8635571.html

时间: 2024-10-09 14:03:36

POJ 1236 Network of Schools(tarjan求强连通分量+思维)的相关文章

[ACM] poj 1236 Network of Schools (有向强连通分量)

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11407   Accepted: 4539 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li

poj1236 Network of Schools ,求强连通分量(Tarjan算法),缩点

题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点 顶点数<= 100 求完强连通分量后,缩点,计算每个点的入度,出度. 第一问的答案就是入度为零的点的个数, 第二问就是max(n,m) // 入度为零的个数为n, 出度为零的个数为m. //kuangbin巨巨分析很棒! #include<cstdio> #include<cstring>

Poj 1236 Network of Schools (Tarjan)

题目链接: Poj 1236 Network of Schools 题目描述: 有n个学校,学校之间有一些单向的用来发射无线电的线路,当一个学校得到网络可以通过线路向其他学校传输网络,1:至少分配几个网络才能够让所有学校被网络覆盖?2:至少要加几条线路就能做到在任意一个学校安装网络都可以覆盖全部学校? 解题思路: 先用Tarjan对强连通分量进行缩点,然后对缩点以后的图进行处理,统计图中节点出度为零的有多少,入度为零的有多少个? 因为入度为零的点不能由其他的点到达,在每个入度为零的节点安装网络可

POJ 1236 Network of Schools (Tarjan + 缩点)

Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12240   Accepted: 4871 Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a li

POJ 1236 Network of Schools(强连通 Tarjan+缩点)

POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入?几条边使得有向图成为一个强连通图. 分析: 跟HDU 2767 Proving Equivalences(题解)一样的题目,只是多了个问题,事实上转化成DAG后就不难考虑了,事实上仅仅要选择入度为0的点即可了. 代码: /* * Author: illuz <iilluzen[at]gmail.com> *

POJ 1236 Network of Schools(强连通分量)

POJ 1236 Network of Schools 链接:http://poj.org/problem?id=1236 题意:有一些学校连接到一个计算机网络.这些学校之间达成了一个协议:每个学校维护着一个学校列表,它向学校列表中的学校发布软件.注意,如果学校B 在学校A 的列表中,则A 不一定在B 的列表中. 任务A:计算为使得每个学校都能通过网络收到软件,你至少需要准备多少份软件拷贝. 任务B:考虑一个更长远的任务,想确保给任意一个学校发放一个新的软件拷贝,该软件拷贝能发布到网络中的每个学

poj 1236 Network of Schools 【强连通图】

题目:poj 1236 Network of Schools 类似题目hdoj 2767 3836 /*******以下kuang大神的解释,写的很好就不解释了*************************/ 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大意:N(2<N<100)各学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输,问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件.2,至少需要添加几条传输线路(边),使任

UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】

Road Networks Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4262 Description There is a road network comprised by M<tex2html_verbatim_mark> roads and N<tex2html_verbatim_mark> cities.

UESTC 901 方老师抢银行 --Tarjan求强连通分量

思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大.所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个DAG(有向无环图),然后跑一遍DFS,不断加上遍历点的权值,如果到了网吧,则更新一遍答案,因为可以出去了. 求强连通分量时,如果low[u] == dfn[u],说明形成了一个新的强连通分量,且根为u.具体求强连通分量见:http://www.cnblogs.com/whatbeg/p/377642