强联通块tarjan算法
http://poj.org/problem?id=1236
第一问:需要几个学校存在软件,才能通过传递,使得所有的学校都有软件
用tarjan算法求出强联通分量后,将每个联通分量缩成一个点,那么问题1的答案就是入度为0的点的个数
为什么?入度为0的点,肯定不能通过其他学校传送软件给他,所以他必须存在一份软件
第二问:需要加几条边,才能使得图强联通
缩点后,a为所有入度为0的点的个数,b为所有出度为0的点的个数,那么答案就是max(a,b)
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
using namespace std;
const int N = + ;
vector<int> G[N];
stack<int> st;
bool vis[N];
int sccno[N],pre[N],lowlink[N],in[N],out[N],dfs_clock,scc_cnt;
int min(const int &a, const int &b)
{
return a < b ? a : b;
}
void tarjan(int u)
{
pre[u] = lowlink[u] = ++dfs_clock;
st.push(u);
for(int i=; i<G[u].size(); ++i)
{
int v = G[u][i];
if(!pre[v])
{
tarjan(v);
lowlink[u] = min(lowlink[u],lowlink[v]);
}
else if(!sccno[v])
lowlink[u] = min(lowlink[u],pre[v]);
}
if(lowlink[u]==pre[u])
{
scc_cnt++;
for(;;)
{
int x = st.top();st.pop();
sccno[x] = scc_cnt;
if(x==u) break;
}
}
}
void find_scc(int n)
{
for(int i=; i<=n; ++i)
if(!pre[i])
tarjan(i);
}
int main()
{
int n,i,a,b;
scanf("%d",&n);
for(a=; a<=n; ++a)
{
while(scanf("%d",&b),b)
{
G[a].push_back(b);
vis[b] = true;
}
}
find_scc(n);
for(i=; i<=scc_cnt; ++i) in[i] = out[i] = ;
for(int u=; u<=n; ++u)
for(i=; i<G[u].size();++i)
{
int v = G[u][i];
if(sccno[u] != sccno[v]) in[sccno[v]] = out[sccno[u]] = ;
}
a = b = ;
for(i=; i<=scc_cnt; ++i)
{
if(in[i]) a++;
if(out[i]) b++;
}
int ans = a > b ? a : b;
if(scc_cnt == ) ans = ;
printf("%d\n%d\n",a,ans);
return ;
}
强联通块tarjan算法的更多相关文章
- 强联通分量-tarjan算法
定义:在一张有向图中,两个点可以相互到达,则称这两个点强连通:一张有向图上任意两个点可以相互到达,则称这张图为强连通图:非强连通图有极大的强连通子图,成为强联通分量. 如图,{1},{6}分别是一个强 ...
- 有向图的强联通分量 Tarjan算法模板
//白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...
- hdu2767 Proving Equivalences,有向图强联通,Kosaraju算法
点击打开链接 有向图强联通,Kosaraju算法 缩点后分别入度和出度为0的点的个数 answer = max(a, b); scc_cnt = 1; answer = 0 #include<c ...
- [vios1023]维多利亚的舞会3<强联通分量tarjan>
题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...
- POJ 2186-Popular Cows (图论-强联通分量Korasaju算法)
题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认 ...
- POJ 3592 Instantaneous Transference(强联通分量 Tarjan)
http://poj.org/problem?id=3592 题意 :给你一个n*m的矩阵,每个位置上都有一个字符,如果是数字代表这个地方有该数量的金矿,如果是*代表这个地方有传送带并且没有金矿,可以 ...
- poj-3177(并查集+双联通分量+Tarjan算法)
题目链接:传送门 思路: 题目要将使每一对草场之间都有至少两条相互分离的路径,所以转化为(一个有桥的连通图至少加几条边才能变为双联通图?) 先求出所有的桥的个数,同时将不同区块收缩成一个点(利用并查集 ...
- 双联通的tarjan算法
转自:https://www.zhihu.com/question/40746887/answer/88428236 连通分量有三种∶边双连通分量,点双连通分量,强连通分量,前两种属于无向图,后一种属 ...
- POJ 3114 Countries in War(强联通分量+Tarjan)
题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. #include ...
随机推荐
- Swift - 给表格添加编辑功能(删除,插入)
1,下面的样例是给表格UITableView添加编辑功能: (1)给表格添加长按功能,长按后表格进入编辑状态 (2)在编辑状态下,第一个分组处于删除状态,第二个分组处于插入状态 (3)点击删除图标,删 ...
- HDU4911-Inversion(树状数组)
Inversion Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Tota ...
- Repeater
- C++异常中的堆栈跟踪
C++语言的运行时环境是基于栈的环境,堆栈跟踪(trace stack)就是程序运行时能够跟踪并打印所调用的函数.变量及返回地址等,C++异常中的堆栈跟踪就是当程序抛出异常时,能够把导致抛出异常的语句 ...
- Android短信监听(二)——利用ContentObserver实现短信监听
MainActivity例如以下: package cc.testsmslistener; import cc.testsmslistener.SMSContentObserver.MessageLi ...
- 二、Cocos2dx概念介绍(游戏开发中不同的坐标系,cocos2dx锚点)
注:ccp是cocos2dx中的一个宏定义,#define ccp(__X__,__Y__)CCPointMake((float)__X__, (float)__Y__),在此文章中表示坐标信息 1. ...
- ANTS Performance Profiler 破解使用
http://blog.csdn.net/wangjia184/article/details/7746089
- Java泛型之<T>
这里不讲泛型的概念和基础知识,就单纯的就我的理解说一下泛型中的<T> 一. <T> 下面的一段码就可以简单使用了<T>参数,注释就是对<T>的解释. p ...
- nginx 区分pc和mobile 到不同的404页面
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry|vivo)') { set $mobile_request '1'; } ...
- Linux 技巧之 Grub 超实用技巧
1. 简单介绍 什么是 GRUB?GRUB 全名Grand Unified Boot Loader,它是一个引导装入器 -- 它负责装入内核并引导 Linux 系统.GRUB 还能够引导其他操作系统, ...