越狱(break)

【问题描述】
Michael为救哥哥身陷囹圄,被关进foxriver监狱。为准备越狱,他需要散布消息给监狱中其他人来共同协作,但是监狱中鱼龙混杂,分成各个小团体,内部消息传递单向传输。问题1:初始至少需要向多少个透漏消息,使得监狱内所有人都获知消息。
问题2,至少需要添加几条传输线路(边),使任意向一个人散步消息后,经过若干次传送,监狱内所有的人最终都能得到消息。
【输入格式】
从文件break.in中输入数据。
输入的第一行包含一个整数 N:监狱人数(2 <= N <= 100)。用前 N 个正整数标识每个人。接下来 N 行中每行都表示一个消息传递列表(分发列表)。第 i+1 行包括 i 的接收消息的人的标识符。每个列表用 0 结束。空列表只用一个 0 表示。
【输出格式】
输出到文件break.out中。
输出的第一行包含一个正整数:问题1的解。第二行应该包含问题2的解。
【样例输入】
5
2 4 3 0
4 5 0
0
0
1 0
【样例输出】
1
2

题解

问题二即为HUD2767的问题,简单来说就是tarjan跑完DAG后询问还要加多少边又可以变成变成一个强连通分量。
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;

code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#define Mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=110;
int n,m,len,Tim,cnt;
stack<int> q;
struct node{int to,next;
}e[maxn*maxn];
bool flag[maxn];
void Insert(int,int);
void Dfs(int );
int Low[maxn],head[maxn],dfn[maxn],a[maxn]={0},ru[maxn],w[maxn],chu[maxn],Belong[maxn];
int ma(){scanf("%d",&n);memset(head,-1,sizeof(head));for(int i=1;i<=n;i++){int m;while(scanf("%d",&m),m!=0)Insert(i,m);}for(int i=1;i<=n;i++)if(dfn[i]==0)Dfs(i);for(int i=1;i<=n;i++){int tot=0;for(int j=head[i];j!=-1;j=e[j].next){int h=e[j].to;if(Belong[h]!=Belong[i]){ru[Belong[h]]++;chu[Belong[i]]++;}}   }int ans1=0,ans2=0;for(int i=1;i<=cnt;i++){if(ru[i]==0)ans1++;if(chu[i]==0)ans2++;}ans2=max(ans2,ans1);for(int i=2;i<=n;i++){if(Belong[i]!=Belong[i-1])break;if(i==n)ans2=0;}printf("%d\n%d",ans1,ans2);
}
void Insert(int  x,int y)
{len++;e[len].to=y;e[len].next=head[x];head[x]=len;
}
void Dfs(int x){Tim++;dfn[x]=Low[x]=Tim;q.push(x);flag[x]=1;for(int i=head[x];i!=-1;i=e[i].next){int t=e[i].to;if(dfn[t]==0){Dfs(t);Low[x]=min(Low[x],Low[t]);}else if(flag[t]==1)Low[x]=min(Low[x],dfn[t]);}if(dfn[x]==Low[x]){cnt++;int k=0;do{k=q.top();q.pop();flag[k]=0;Belong[k]=cnt;}while(k!=x);}
}
int hhh=ma();
int main(){;}

这种思维方式还是很值得背板子的同学们学习。

HUD2767 进阶版 [强连通分量]相关推荐

  1. 杭电ACM-LCY算法进阶培训班-专题训练(强连通分量)

    点对统计 最大点权 点对统计 Problem Description 给定一个有向图,统计有多少点对u,v(1≤u<v≤n)u,v(1≤u<v≤n)u,v(1≤u<v≤n)满足uuu ...

  2. 图论——强连通分量(Tarjan算法)

    文章目录 强连通分量 利用Tarjan算法求强连通分量 来一道例题练手(USACO08DEC) 图论文章汇总 强连通分量 什么是强连通图? 如果一个有向图中,存在一条回路,所有的结点至少被经过一次,这 ...

  3. 图论学习-有向图强连通分量

    文章目录 有向图强连通分量 1.定义: 2.基本术语与概念 2.1 边的概念 2.2 缩点 2.3 时间戳 3. tarjan求强连通分量(SCC) 3.1 原理 3.2 步骤 3.3 模板 3.3. ...

  4. 【图论·强连通分量scc】hdu6072Logical Chain

    非常有灵性的一道强连通分量.乍一看是道模板题,然而需要用bitset优化时间复杂度至1/64:bitset什么鬼啊喂,很佩服赛场上唯一做出来的大佬orz: 常规部分,学习了scc模板求强连通分量: 第 ...

  5. 极小连通子图和极大连通子图_强连通分量与拓扑排序

    前言 由于GacUI里面开始多处用上拓扑排序,我决定把之前瞎JB搞出来的算法换掉,换成个正式的.之前我自己弄了个写起来很简单的算法,然后每一处需要用到的地方我就重新做一遍.当然这样肯定也是不行的,我觉 ...

  6. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)...

    转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2194090a96bbed2db1351de8.html 基本概念: 1.割点:若删掉某点后,原连通图 ...

  7. 特朗普“模仿”奥巴马?进阶版换脸技术DeepFakes来了

    整理 | 费棋 出品 | AI科技大本营 DeepFakes,这种能够移花接木的技术,它能将图像或视频中把一张脸替换成另一张脸. 去年 12 月,一个名 Reddit 用户用 DeepFakes 技术 ...

  8. HDU4635(强连通分量+Kosaraju算法)

    题意:给出一个有向图,最多添加多少条边使这个图依然不是强连通图:当这个图是强连通图时,输出-1: 求解思路:强连通分量求解: 强连通图:在有向图中,任意节点除法都可以到达其余所有节点,则称为强连通图. ...

  9. poj3352(强连通分量)

    题意:添加多少边才能使这个无向图为双连通分量. 注意:双连通分量适用于无向图:而强连通分量适用于有向图.但是这两个概念都是一样的. #include<iostream> #include& ...

最新文章

  1. 【总结整理】登录模块---摘自《人人都是产品经理》
  2. java url 返回值_java提交url后返回值怎么取
  3. 要市场导向,不要销售导向,更不要个人导向(转)
  4. 二值形态学操作、图像的边缘检测、图像编码
  5. 有哪些典型的「学生思维」?
  6. JDBC第二篇 【PreparedStatment、批处理、处理二进制、自动主键、调用存储过程、函数】...
  7. java stream 使用局部变量
  8. 【动态规划】开心的小明
  9. linux块设备缓存bcache
  10. 360浏览器升级_社畜必备!360浏览器上线“文档”功能 一键开启云办公
  11. 使用PHP来简单的创建一个RPC服务
  12. RocketMQ源码-基于Netty的通信层设计
  13. windows 网络编程大汇总
  14. Argparse 使用
  15. 计算机无法进行磁盘,电脑硬盘无法分区怎么办
  16. ssm运动器材共享平台毕业设计源码201816
  17. 爱了爱了!丰巢智能政务柜真的太实用了
  18. KVM虚拟机支持虚拟化(kvm虚拟化嵌套)
  19. ES6中字符串和数组新增的方法
  20. DBeaver安装及使用

热门文章

  1. 【Python】回数是指从左向右读和从右向左读都是一样的数,例如12321,909。请利用filter()筛选出回数
  2. C#OOP之十五 String类StringBuilder类
  3. MODIS数据所有产品介绍与下载地址
  4. Python爬虫实战之爬取QQ音乐数据!QQ音乐限制太多了!
  5. zstack信道_ZSTACK修改信道和PANID
  6. laydate动态设置MarkMinMax
  7. 程序员面试题精选100题
  8. 1024程序员节,我被喷上了热搜!
  9. 记录一个设备旁挂ikuai后收不到回包TTL为1的问题
  10. 2021数学建模c题看法