题目链接:https://vjudge.net/contest/219056#problem/H

题意:先输入n,代表接下来有n个点,接下来n行,第i行里面的数(假设是)a,b...0(到0表示结束),表示点i和a,b有一条从i到a,b的有向边,现在叫我们求出两个答案,

第一个答案就是至少要选择几个点作为起点,才可以到达所有的点,

第二个答案就是至少要添加几条有向边才可以使得每次随便选择一个点都可以到达其他所有点(整个图就是一个强连通分量)。

思路:首先计算第一个答案:至少要几个点作为起点才可以到达其他所有点,如果是同一个强连通分量的点肯定可以相互到达,那我们就先缩点,得到一个有向无环图,那么我们的答案是不是就是缩点之后的图中入度为0的点,因为通过这些入度为0的点一定可以到达其他入度非0的点,那么我们的第一个答案就是缩点之后入度为0的点的个数。

第二个答案:至少要增加几条有向边才可以使这个图里面的点可以两两相互到达(只有一个强连通分量),首先在有向图里面如果没有入度为0并且也没有出度为0的点,那么这个图就是强连通的(应该不包括自己指向自己),在我们缩点之后,对于那些入度为0的点,我们想要到达,则必须要有一条有向边到达这些入度为0的点,假设入度为0的点的数量是in_um,对于出度为0,的点,我们必须至少连接一条有向边使得这个点可以到达其他点,假设出度为0的点的数量是out_num,那么第二个答案就是max(in_num,out_num),因为我们可以增加有向边从出度为0的点指向入度为0的点,答案就是更大的数。

这里有个大坑就是如果缩点之后强连通分量数目为1,那么直接输出1 0就可以了,特例,我还是百度才知道的。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 105
vector<int>vec[maxn];
int n,m,k,t;
int vis[maxn];
int dfn[maxn],low[maxn],color[maxn],s[maxn],time,ans,top;
int in[maxn],out[maxn],flag[maxn][maxn];
void init()
{
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
memset(flag,,sizeof(flag));
for(int i=;i<=n;i++)
{
vec[i].clear();
}
time=top=ans=;
}
void DFS(int u)
{
dfn[u]=low[u]=++time;
s[top++]=u;
vis[u]=true;
for(int i=;i<vec[u].size();i++)
{
int v=vec[u][i];
if(!dfn[v])
{
DFS(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
ans++;
int v;
do{
v=s[--top];
vis[v]=false;
color[v]=ans;//染色
}while(u!=v);
}
}
void tarjan()
{
for(int i=;i<=n;i++)
{
if(!dfn[i])
DFS(i);
}
}
void cal()//计算出入度
{
for(int i=;i<=n;i++)
{
for(int j=;j<vec[i].size();j++)
{
int a=color[i];
int b=color[vec[i][j]];
if(a!=b)
{
if(flag[a][b]==)//标记a和b之间有没有有向边
{
out[a]++;
in[b]++;
flag[a][b]++;
} }
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for(int i=;i<=n;i++)
{
int v;
while(scanf("%d",&v)&&v)
{
vec[i].push_back(v);
}
}
tarjan();
if(ans==)//特例
{
printf("1\n0\n");
continue;
}
cal();//计算出入度
int in_num=,out_num=;//入度为0和出度为0的点的数目
int sum1=,sum2=;
for(int i=;i<=ans;i++)//注意ans,这是缩点之后点的数量,不要写成n了
{
if(!in[i])
in_num++;
if(!out[i])
out_num++;
}
sum1=in_num;
sum2=max(in_num,out_num);
printf("%d\n%d\n",sum1,sum2);
}
return ;
}

缩点+出入度 poj1236的更多相关文章

  1. poj 1236 Network of Schools(强连通、缩点、出入度)

    题意:给出一个有向图.1:问至少选出多少个点,才能沿有向边遍历所有节点.2:问至少加多少条有向边,使原图强连通. 分析:第一个问题,缩点后找所有树根(入度为0).第二个问题,分别找出入度为0和出度为0 ...

  2. Tarjan缩点求入度为零的点的个数问题

    Description: 一堆人需要联系,但如果x 可以联系 y,你联系了x就不用联系y了,你联系一个人都会有固定的花费,问你最小联系多少人,和最小花费 Solution: Tarjan缩点,求出缩点 ...

  3. POJ1236 (强连通分量缩点求入度为0和出度为0的分量个数)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13804   Accepted: 55 ...

  4. poj 2553 The Bottom of a Graph(强连通、缩点、出入度)

    题意:给出一个有向图G,寻找所有的sink点.“sink”的定义为:{v∈V|∀w∈V:(v→w)⇒(w→v)},对于一个点v,所有能到达的所有节点w,都能够回到v,这样的点v称为sink. 分析:由 ...

  5. poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11047   Accepted: 4725 ...

  6. poj 1659 Frogs' Neighborhood(出入度、可图定理)

    题意:我们常根据无向边来计算每个节点的度,现在反过来了,已知每个节点的度,问是否可图,若可图,输出一种情况. 分析:这是一道定理题,只要知道可图定理,就是so easy了  可图定理:对每个节点的度从 ...

  7. HDU 4635 Strongly connected(强连通分量,变形)

    题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...

  8. poj1236强连通缩点

    题意:给出每个学校的list 代表该学校能链接的其他学校,问1:至少给几个学校资源使所有学校都得到:2:至少加多少个边能让所有学校相互连通: 思路:1:找出缩点后入度为零的点个数  2:找出缩点后入度 ...

  9. poj1236 Network of Schools ,有向图求强连通分量(Tarjan算法),缩点

    题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点.才干做到从这些顶点出发,能够到达所有顶点 2) 至少要加多少条边.才干使得从不论什么一个顶点出发,都能到达所有顶点   ...

随机推荐

  1. $tojson和json.stringify的区别

    JSON.stringify(),将value(Object,Array,String,Number...)序列化为JSON字符串 JSON.parse(), 将JSON数据解析为js原生值 toJS ...

  2. jquery 全选操作

    $(function(){ $("#checkedAll").change(function(){ if(this.checked){ $(".checkSingle&q ...

  3. Spring boot 启动配置原理

    配置在META-INF/spring.factories 有几个主要的类 ApplicationContextInitializer    创建SpringAplication SpringAppli ...

  4. dshow采集过程

    捕捉静态图片常用的filter是Sample Graber filter,它的用法参考手册.然后将捕捉filter的静态PIN连接到Sample Grabber,再将Sample Grabber连接到 ...

  5. Linux tcpdump命令使用方法

    tcpdump是Linux上常用的抓包命令,用于截取网络分组并输出分组内容,常用于网络问题分析和排查. tcpdump语法 tcpdump [-i 接口] [-nn] [-w 文件名] [-c 次数] ...

  6. ES6的export和import

    export import 的4种搭配 非默认 拿函数举例,常量,变量,类也可以 // 1 可以多个export--------import带上{} export var a="123&qu ...

  7. 16.2 profile 显示或者隐藏页面 修改密码

    我们auth在clent端有更加强大的功能 显示或者隐藏component 或者 我们可以阻止或者允许某个用户访问url

  8. Hibernate 再接触 多对一与一对多

    多对一单向关联 数据库设计: 错误做法:在多方加外键 在多这一方加外键 第一种 annotation Group.java package com.bjsxt.hibernate; import ja ...

  9. MVC part4

    SpringMVC 注解 @Controller 负责注册一个bean 到spring 上下文中,bean 的ID 默认为类名称开头字母小写,你也可以自己指定, 如下 方法一: @Controller ...

  10. Oracle 查询版本号

    select * from v$version; -- 或 select banner from sys.v_$version;