缩点+出入度 poj1236
题目链接: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的更多相关文章
- poj 1236 Network of Schools(强连通、缩点、出入度)
题意:给出一个有向图.1:问至少选出多少个点,才能沿有向边遍历所有节点.2:问至少加多少条有向边,使原图强连通. 分析:第一个问题,缩点后找所有树根(入度为0).第二个问题,分别找出入度为0和出度为0 ...
- Tarjan缩点求入度为零的点的个数问题
Description: 一堆人需要联系,但如果x 可以联系 y,你联系了x就不用联系y了,你联系一个人都会有固定的花费,问你最小联系多少人,和最小花费 Solution: Tarjan缩点,求出缩点 ...
- POJ1236 (强连通分量缩点求入度为0和出度为0的分量个数)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13804 Accepted: 55 ...
- poj 2553 The Bottom of a Graph(强连通、缩点、出入度)
题意:给出一个有向图G,寻找所有的sink点.“sink”的定义为:{v∈V|∀w∈V:(v→w)⇒(w→v)},对于一个点v,所有能到达的所有节点w,都能够回到v,这样的点v称为sink. 分析:由 ...
- poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11047 Accepted: 4725 ...
- poj 1659 Frogs' Neighborhood(出入度、可图定理)
题意:我们常根据无向边来计算每个节点的度,现在反过来了,已知每个节点的度,问是否可图,若可图,输出一种情况. 分析:这是一道定理题,只要知道可图定理,就是so easy了 可图定理:对每个节点的度从 ...
- HDU 4635 Strongly connected(强连通分量,变形)
题意:给出一个有向图(不一定连通),问最多可添加多少条边而该图仍然没有强连通. 思路: 强连通分量必须先求出,每个强连通分量包含有几个点也需要知道,每个点只会属于1个强连通分量. 在使图不强连通的前提 ...
- poj1236强连通缩点
题意:给出每个学校的list 代表该学校能链接的其他学校,问1:至少给几个学校资源使所有学校都得到:2:至少加多少个边能让所有学校相互连通: 思路:1:找出缩点后入度为零的点个数 2:找出缩点后入度 ...
- poj1236 Network of Schools ,有向图求强连通分量(Tarjan算法),缩点
题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点.才干做到从这些顶点出发,能够到达所有顶点 2) 至少要加多少条边.才干使得从不论什么一个顶点出发,都能到达所有顶点 ...
随机推荐
- 数电——全减器分析(用74HC138设计提示)
-1=1(即Di=1). Di=(Y1' * Y2' * Y4' * Y7')'可以得到74HC138来表示,(注意:Ai,Bi,Ci-1的各自位权对应A2,A1,A0) Ci同理可得.
- UI5-学习篇-9-本地Eclipse UI5应用发布到SAP前端服务器
参考路径: https://blogs.sap.com/2017/11/19/sap-fiori-ui5-application-deployment/ 1.准备环境 2.上载SAP-FIORI前端服 ...
- 16_虚拟dom和dom diff算法
虚拟dom的作用:是为了减少操作真实的dom 初始化显示界面的过程: 1.创建虚拟dom树——>真实dom树——>绘制页面显示 更新界面的过程: 2.绘制页面显示——>setStat ...
- Delphi 集合和字符串互转
集合和字符串互转 集合: type TSocketState = (ssDisconnecting, ssDisconnected, ssConnected, ssConnecting, s ...
- jquery 设计的扩展---初级
1. 写一个构造函数G,调用G 时,返回G上的fn 对象的init() 的实例 2.设置G.fn 的指向,使用G.fn 与G.prototype指向同一个对象 2.1 重写G.prototype 对象 ...
- CTags配好后仍找不到函数定义的问题
若把CTags的Setting-User配好后,Navigation to Defination一个类或者函数发现仍无法跳转时,可以把需要查找的文件夹拉进sublime任一窗口中再试试. 因为CTag ...
- JS 实现分页打印
在调用window.print()时,可以实现打印效果,但内容太多时要进行分页打印. 在样式中有规定几个打印的样式 page-break-before和page-break-after CSS属性并不 ...
- JDBC有哪些接口
1 实现Driver接口的对象是JDBC进行数据库访问的开始,可以通过java.lang.Class类的forName(),动态加载驱动程序. Class.forName("驱动程序&quo ...
- 一张图知道HTML5布局(图)
- PHP脚本不报错的两点原因
-------------------------------------------------------------------------------------------------- P ...