Network of Schools---poj1236(强连通分量)
题意:学校有一些单向网络,现在需要传一些文件
求:1,求最少需要向几个学校分发文件才能让每个学校都收到,
2,需要添加几条网络才能从任意一个学校分发都可以传遍所有学校。
解题思路(参考大神的):
1. 求出所有强连通分量
2. 每个强连通分量缩成一点,则形成一个有向无环图DAG。
3. DAG上面有多少个入度为0的顶点,问题1的答案就是多少
在DAG上要加几条边,才能使得DAG变成强连通的,问题2的答案就是多少
加边的方法:
要为每个入度为0的点添加入边,为每个出度为0的点添加出边
假定有 n 个入度为0的点,m个出度为0的点,如何加边?
把所有入度为0的点编号 0,1,2,3,4 ....N -1
每次为一个编号为i的入度0点可达的出度0点,添加一条出边,连到编号为(i+1)%N 的那个出度0点,
这需要加n条边
若 m <= n,则
加了这n条边后,已经没有入度0点,则问题解决,一共加了n条边
若 m > n,则还有m-n个入度0点,则从这些点以外任取一点,和这些点都连上边,即可,这还需加m-n条边。
所以,max(m,n)就是第二个问题的解
此外:当只有一个强连通分支的时候,就是缩点后只有一个点,虽然入度出度为0的都有一个,但是实际上不需要增加清单的项了,所以答案是1,0;
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <algorithm>
- #include <vector>
- #include <queue>
- #include <cmath>
- #include <cstring>
- #include <stack>
- using namespace std;
- #define INF 0xfffffff
- #define N 10060
- int Out[N],In[N], n;
- int low[N], dfn[N], num, cnt, Time, vis[N], belong[N];
- vector<int> G[N];
- stack<int>sta;
- void Init()
- {
- Time=num=cnt=;
- for(int i=;i<=n;i++)
- G[i].clear();
- memset(dfn, , sizeof(dfn));
- memset(low, , sizeof(low));
- memset(vis, , sizeof(vis));
- memset(belong, , sizeof(belong));
- memset(Out, , sizeof(Out));
- memset(In, , sizeof(In));
- }
- void Tarjan(int u)
- {
- dfn[u] = low[u] = ++Time;
- int len = G[u].size(), v;
- sta.push(u);
- vis[u] = ;
- for(int i=; i<len; i++)
- {
- v = G[u][i];
- if(dfn[v]==)
- {
- Tarjan(v);
- low[u] = min(low[u], low[v]);
- }
- else if(vis[v]==)
- {
- low[u] = min(dfn[v], low[u]);
- }
- }
- if(low[u]==dfn[u])
- {
- ++num;
- do
- {
- v = sta.top();
- belong[v] = num;// 缩点;
- sta.pop();
- vis[v] = ;
- }while(u!=v);
- }
- }
- int main()
- {
- int a, ans1, ans2, ans, u, v;
- while(scanf("%d", &n)!=EOF)
- {
- Init();
- for(int i=; i<=n; i++)
- {
- while(scanf("%d", &a), a)
- {
- G[i].push_back(a);
- }
- }
- for(int i=; i<=n; i++)
- if(!dfn[i])
- Tarjan(i);
- ans1 = ans2 = ;
- for(int i=; i<=n; i++)
- {
- int len=G[i].size();
- for(int j=; j<len; j++)
- {
- u = belong[i]; v = belong[G[i][j]];
- if(u!=v)
- {
- Out[u]++;
- In[v]++;
- }
- }
- }
- for(int i=; i<=num; i++)
- {
- if(Out[i]==)ans2++;
- if(In[i]==)ans1++;
- }
- ans = max(ans1, ans2);
- if(num==)
- printf("1\n0\n");
- else
- printf("%d\n%d\n", ans1, ans);
- }
- return ;
- }
Network of Schools---poj1236(强连通分量)的更多相关文章
- poj1236 Network of Schools【强连通分量(tarjan)缩点】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html ---by 墨染之樱花 [题目链接]http://poj.org/pr ...
- POJ 1236 Network of Schools(强连通分量/Tarjan缩点)
传送门 Description A number of schools are connected to a computer network. Agreements have been develo ...
- POJ1236_A - Network of Schools _强连通分量::Tarjan算法
Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are connected to a compute ...
- poj 1236 Network of Schools(又是强连通分量+缩点)
http://poj.org/problem?id=1236 Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Su ...
- POJ 1236 Network of Schools(强连通分量)
POJ 1236 Network of Schools 题目链接 题意:题意本质上就是,给定一个有向图,问两个问题 1.从哪几个顶点出发,能走全全部点 2.最少连几条边,使得图强连通 思路: #inc ...
- poj 1236 Network of Schools (强连通分量+缩点)
题目大概: 每个学校都可以把软件复制好,交给它名单上的学校. 问题A:把软件复制成几份,然后交给不同的学校,所有学校才能够都有软件. 问题B:添加几条边,能使得这个图变成强连通图. 思路: 找出所有的 ...
- POJ 1236 Network of Schools 有向图强连通分量
参考这篇博客: http://blog.csdn.net/ascii991/article/details/7466278 #include <stdio.h> #include < ...
- P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools
P2746 [USACO5.3]校园网Network of Schools// POJ1236: Network of Schools 题目描述 一些学校连入一个电脑网络.那些学校已订立了协议:每个学 ...
- POJ 1236 Network of Schools(强连通 Tarjan+缩点)
POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意: 给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...
- POJ1236 Network of Schools (强连通)(缩点)
Network of Schools Time Limit: 1000MS ...
随机推荐
- Centos下查看和修改网卡Mac地址
linux/Centos下查看网卡Mac地址,输入命令: #ifconfig -a eth0 Link encap:Ethernet HWaddr 00:e4:56:2E:D8:20 00:e4:56 ...
- C++类中静态成员函数
引述自<深入探索C++对象模型>2001:5:1版次,p-150 static member functions的主要特性就是它没有this指针,所以: 1.它不能直接存取其所在class ...
- Unity3d导出安卓版本
1. 要想导出安卓版,就必须要安装安卓 SDK,这个可以去这里下载. http://developer.android.com/sdk/index.html. 当我们打开后就是看见这个了. 2.当我 ...
- Unity在协程内部停止协程自身后代码执行问题
当在协程内部停止自身后,后面的代码块还会继续执行,直到遇到yield语句才会终止. 经测试:停止协程,意味着就是停止yield,所以在停止协程后,yield之后的语句也就不会执行了. 代码如下: us ...
- MathType编辑双向斜箭头的教程
箭头是一个很常见的符号,不只是在数学中,在各个方面出现的频率都很高,因此在数学公式中出现时,用MathType公式编辑器编辑公式时也要尽量地能够编辑出这些符号.箭头符号在MathType中有很多,使用 ...
- JavaScript正则表达式1
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要.正则表达式就是用于描述这些规则的工具.换句话说,正则表达式就是记录文本规则的代码. 正则表达式可以: •数据有效性验证.可以 ...
- Windows上Tomcat启动,服务中没有Tomcat
首先需要查看Tomcat的bin目录下是否有service.bat,如果没有需要去下载一版bin目录下有service.bat的Tomcat,只有Windows版本的Tomcat的bin目录下才有se ...
- Redis(二)-- 发布订阅、事务、安全、持久化
一.Redis发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 打开两个窗口:session1 和 session2 在sess ...
- sql语句如何删除最后一条和第一条信息
这是先前建好的SQL数据库中的test表, sql语句: delete a from test a,(select max(id) id from test) b where a.id = b.id ...
- windows 上驱动阻止关机重启操作
Windows 上关机重启有很多相关的操作 HOOK 一个点搞不定 具体需要以下 4 处来布控 SSDT HOOK NtInitiatePowerAction 函数 ,直接返回失败废掉这个函数 SS ...