题意:一张有向图,一问至少给几个点发送软件,才能让所有点都能收到软件;二问是至少添加几条边才能让整个图是一个连通分量;

分析:一般求连通分量都会求缩点,在这里缩点之后,生成一张新的图,在新的图中求每一个点的出度,入度。答案就是sum(入度=0),max(sum(出度 == 0),sum(入度 == 0));

注意:如果整张图本来就是一个强连通分量,需要特判。因为它出度,入度都等于0,即max(1,1) = 1,但是实际上不用再补充边了,应该是0,按照上面的分析答案就错了。

 ///POJ1236
///时间复杂度也是O(N+M)
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
#include <iostream>
#define repu(i,a,b) for(int i=a;i<b;i++)
using namespace std;
#define N 105 /// 题目中可能的最大点数
stack<int>sta; /// 存储已遍历的结点
vector<int>gra[N]; /// 邻接表表示图
int dfn[N]; /// 深度优先搜索访问次序
int low[N]; /// 能追溯到的最早的次序
int InStack[N];
/// 检查是否在栈中(2:在栈中,1:已访问,且不在栈中,0:不在)
vector<int> Component[N]; /// 获得强连通分量结果
int InComponent[N]; /// 记录每个点在第几号强连通分量里
int Index,ComponentNumber;/// 索引号,强连通分量个数
int n, m; /// 点数,边数
int d[N][N],chu[N],ru[N]; void init()///清空容器,数组
{
memset(dfn, , sizeof(dfn));
memset(low, , sizeof(low));
memset(chu, , sizeof(chu));
memset(ru, , sizeof(ru));
memset(InStack, , sizeof(InStack));
Index = ComponentNumber = ;
for (int i = ; i <= n; ++ i)
{
gra[i].clear();
Component[i].clear();
}
repu(i,,n+)
repu(j,,n+)
d[i][j] = ;
while(!sta.empty())
sta.pop();
}
void tarjan(int u)
{
InStack[u] = ;
low[u] = dfn[u] = ++ Index;
sta.push(u);///寻找u所在的强连通分量
for (int i = ; i < gra[u].size(); ++ i)
{
int t = gra[u][i];
if (dfn[t] == )///不在的继续递归
{
tarjan(t);///递归到头了就
low[u] = min(low[u], low[t]);
}
else if (InStack[t] == )///在栈里
{
low[u] = min(low[u], dfn[t]);
}
}
if(low[u] == dfn[u])///sta出栈就是一个强连通分量的
{
++ComponentNumber;///强连通分量个数
while (!sta.empty())
{
int j = sta.top();
sta.pop();
InStack[j] = ;///已访问但不在栈中
Component[ComponentNumber].push_back(j);
///用vector存储第ComponentNumber个强连通分量
InComponent[j]=ComponentNumber;
///记录每个点在第几号强连通分量里
if (j == u)
break;
}
}
}
void input()
{
repu(i,,n+)
{
while(scanf("%d",&m) &&m)
d[i][m] = ,gra[i].push_back(m);///有向图才有强连通分量
}
} void solve(void)
{
for(int i=; i<=n; i++)
if(!dfn[i])
tarjan(i);
if(ComponentNumber == )
{
printf("1\n0\n");
return;
}
///缩点
for(int i=; i<=ComponentNumber; i++)
{
for(int j = ; j < Component[i].size(); j++)
{
for(int k = ; k<=n; k++)
{
if(d[k][Component[i][j]] && k != Component[i][j])
{
int s = InComponent[k];
int t = InComponent[Component[i][j]];
if(s!=t)
{
chu[s]++;
ru[t]++;
}
}
}
}
}
int sum = ,num = ;
for(int i=; i<=ComponentNumber; i++)
{
if(!chu[i])
sum++;
if(!ru[i])
num++;
}
printf("%d\n%d\n",num,max(sum,num));
} int main()
{
while(~scanf("%d",&n))
{
init();
input();
solve();
/*每一个强连通分量的具体数字
for(int i = 1; i <= ComponentNumber; i++)
{
for(int j = 0; j < Component[i].size(); j++)
if(!j)
cout << Component[i][j];
else
cout <<"-->"<< Component[i][j];
cout<<endl;
}
*/
}
return ;
}

POJ 1236 SCC+缩点的更多相关文章

  1. poj 1236 scc强连通分量

    分析部分摘自:http://www.cnblogs.com/kuangbin/archive/2011/08/07/2130277.html 强连通分量缩点求入度为0的个数和出度为0的分量个数 题目大 ...

  2. poj 1236强连通图缩点

    题目链接:http://poj.org/problem?id=1236 #include <cstdio> #include <cmath> #include <algo ...

  3. Network of Schools POJ - 1236(强连通+缩点)

    题目大意 有N个学校,这些学校之间用一些单向边连接,若学校A连接到学校B(B不一定连接到A),那么给学校A发一套软件,则学校B也可以获得.现给出学校之间的连接关系,求出至少给几个学校分发软件,才能使得 ...

  4. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

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

    POJ 1236 Network of Schools(强连通 Tarjan+缩点) ACM 题目地址:POJ 1236 题意:  给定一张有向图,问最少选择几个点能遍历全图,以及最少加入�几条边使得 ...

  6. POJ 1236 Network of Schools - 缩点

    POJ 1236 :http://poj.org/problem?id=1236 参考:https://www.cnblogs.com/TnT2333333/p/6875680.html 题意: 有好 ...

  7. POJ 2186 Popular cows(SCC 缩点)

    Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10, ...

  8. 有向图 加最少的边 成为强连通分量的证明 poj 1236 hdu 2767

    poj 1236: 题目大意:给出一个有向图, 任务一: 求最少的点,使得从这些点出发可以遍历整张图  任务二: 求最少加多少边 使整个图变成一个强连通分量. 首先任务一很好做, 只要缩点 之后 求 ...

  9. POJ 1236——Network of Schools——————【加边形成强连通图】

    Network of Schools Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u ...

随机推荐

  1. 如何从github上面拷贝源码

    有好奇心的朋友们一定都想看一看很多开源项目的源码,那么github就不用说啦,太多的开源项目都把源码放到上面. 博主最近为了学习angularjs也不得不去github上面弄源码,下面将会介绍如何做: ...

  2. Hadoop之Hive(2)--配置Hive Metastore

    Hive metastore服务以关系性数据库的方式存储Hive tables和partitions的metadata,并且提供给客户端访问这些数据的metastore service的API.下面介 ...

  3. 分享 - 最初的JDBC操作步骤

    /* * 1. 注册 */ // 装载注册 SQLServer Driver Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDri ...

  4. XDocument 获取包括第一行的声明(版本、编码)的所有节点

    XDocument保存为xml文件的方法如下: XDocument doc = new XDocument( new XDeclaration("1.0","UTF-8& ...

  5. Export Data from mysql Workbench 6.0

    原文地址:export-data-from-mysql-workbench-6-0 问题描述 I'm trying to export my database, using MySQL Workben ...

  6. eclipse + maven 搭建springMVC+Spring+mybatis 系统

    首先需要下载maven 安装maven插件.自行百度. 1: 创建maven系统 http://huxiaoheihei.iteye.com/blog/1766986 2:添加pom依赖: pom.x ...

  7. ThreadLocal的分享

    最开始的时候打算自己写点什么,但是看了这些博客以后感觉真的不知道应该写点什么了,全部都是好文章,只做分享了,链接如下: 1.http://www.cnblogs.com/dolphin0520/p/3 ...

  8. t检验

    例子:以往通过大规模调查已知某地新生儿出生体重为3.30kg.从该地难产儿中随机抽取35名新生儿作为研究样本,平均出生体重为3.42kg,标准差为0.40kg. 问该地难产儿出生体重是否与一般新生儿体 ...

  9. MUMmer 3使用方法

    DNA和核苷酸的快速比对软件包,基于suffix tree 数据结构,快速.图形化.模块可用于其他软件.可进行大基因组比对.多对多基因组比对. The MUMmer Home Page The MUM ...

  10. Mac下安装Node.js

    今天介绍一下Mac下Node.js的下载安装方法,后面我们安装Bootstrap.Angurlar和jQuery等都是通过Node.js的npm方式的. 1.在必应中搜索“node.js mac”,第 ...