poj2186--tarjan+缩点(有向图的强连通分量中点的个数)
题目大意:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define cls(s,h) memset(s,h,sizeof s)
const int maxn = 1e5 + ;
int n , m ;
int tot;
struct edge
{
int to,from,nxt;
}e[maxn << ]; int head[maxn];
void add_edge(int u , int v ){
e[tot].from = u ;
e[tot].to = v;
e[tot].nxt = head[u];
head[u] = tot++;
} int stack[maxn << ],low[maxn << ],dfn[maxn << ];
int scc,sz[maxn << ],c[maxn << ],st,num;
void init(){
cls(head,-);
cls(e,);
cls(sz,);
scc = ;
st = ;
} void tanjan(int u){
stack[++st] = u;
dfn[u] = low[u] = ++ num;
for(int i = head[u],v; ~i ;i = e[i].nxt){
if(c[v = e[i].to]) continue;
if(dfn[v]) low[u] = min(low[u],dfn[v]);
else tanjan(v),low[u] = min(low[u],low[v]);
}
if(low[u] == dfn[u]){
c[u] = ++ scc; sz[scc] = ;
while(st && u != stack[st])
//SCC number and the scc ge SCC
c[stack[st--]] = scc,sz[scc] ++;
st--;
}
} int out[maxn << ];
int main(int argc, char const *argv[])
{
init();
scanf("%d %d",&n,&m);
for(int i = ,u,v;i <= m ;i ++)
scanf("%d %d",&u,&v),add_edge(u,v); for(int i = ;i <= n;i ++)
if(!dfn[i]) tanjan(i);
for(int i = ;i < tot;i ++)
if(c[e[i].from] != c[e[i].to]) out[c[e[i].from]] ++;
int ans = ;
for(int i = ;i <= scc;i ++)
if(!out[i]) ans = ans ? -: i;
if(~ans) ans = sz[ans];
else ans = ;
printf("%d\n", ans);
return ;
}
//如果没有点被孤立,当出度为0的点多于1个时,
//由DAG图的性质可得,一定不存在一个点能从其他所有点到达。
//只有当出度为0的点的个数等于1时,
//这个出度为0的点才能被其他所有点到达。
//因为如果存在两个,那么就会少一个点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define cls(s,h) memset(s,h,sizeof s)
const int maxn = 1e5 + ;
int n , m ;
int tot;
struct edge
{
int to,from,nxt;
}e[maxn << ]; int head[maxn];
void add_edge(int u , int v ){
e[tot].from = u ;
e[tot].to = v;
e[tot].nxt = head[u];
head[u] = tot++;
} int stack[maxn << ],low[maxn << ],dfn[maxn << ];
int scc,sz[maxn << ],c[maxn << ],st,num;
void init(){
cls(head,-);
cls(e,);
cls(sz,);
scc = ;
st = ;
} void tanjan(int u){
stack[++st] = u;
dfn[u] = low[u] = ++ num;
for(int i = head[u],v; ~i ;i = e[i].nxt){
if(c[v = e[i].to]) continue;
if(dfn[v]) low[u] = min(low[u],dfn[v]);
else tanjan(v),low[u] = min(low[u],low[v]);
}
if(low[u] == dfn[u]){
c[u] = ++ scc; sz[scc] = ;
while(st && u != stack[st])
//强连通分量的编号和其中点的个数
//SCC number and the scc ge SCC
c[stack[st--]] = scc,sz[scc] ++;
st--;
}
} int out[maxn << ];
int main(int argc, char const *argv[])
{
init();
scanf("%d %d",&n,&m);
for(int i = ,u,v;i <= m ;i ++)
scanf("%d %d",&u,&v),add_edge(u,v); for(int i = ;i <= n;i ++)
if(!dfn[i]) tanjan(i);
for(int i = ;i < tot;i ++)
if(c[e[i].from] != c[e[i].to]) out[c[e[i].from]] ++;
int ans = ;
for(int i = ;i <= scc;i ++)
if(!out[i]) ans = ans ? -: i;
if(~ans) ans = sz[ans];
else ans = ;
printf("%d\n", ans);
return ;
}
更新代码
poj2186--tarjan+缩点(有向图的强连通分量中点的个数)的更多相关文章
- Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量
在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...
- Tarjan算法 求 有向图的强连通分量
百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn ...
- Tarjan算法求有向图的强连通分量
算法描述 tarjan算法思想:从一个点开始,进行深度优先遍历,同时记录到达该点的时间(dfn记录到达i点的时间),和该点能直接或间接到达的点中的最早的时间(low[i]记录这个值,其中low的初始值 ...
- 『Tarjan算法 有向图的强连通分量』
有向图的强连通分量 定义:在有向图\(G\)中,如果两个顶点\(v_i,v_j\)间\((v_i>v_j)\)有一条从\(v_i\)到\(v_j\)的有向路径,同时还有一条从\(v_j\)到\( ...
- UVA247- Calling Circles(有向图的强连通分量)
题目链接 题意: 给定一张有向图.找出全部强连通分量,并输出. 思路:有向图的强连通分量用Tarjan算法,然后用map映射,便于输出,注意输出格式. 代码: #include <iostrea ...
- uva11324 有向图的强连通分量+记忆化dp
给一张有向图G, 求一个结点数最大的结点集,使得该结点集中任意两个结点u和v满足,要么u可以到达v, 要么v可以到达u(u和v相互可达也可以). 因为整张图可能存在环路,所以不好使用dp直接做,先采用 ...
- poj2186Popular Cows(Kosaraju算法--有向图的强连通分量的分解)
/* 题目大意:有N个cows, M个关系 a->b 表示 a认为b popular:如果还有b->c, 那么就会有a->c 问最终有多少个cows被其他所有cows认为是popul ...
- 图->连通性->有向图的强连通分量
文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly co ...
- DFS的运用(二分图判定、无向图的割顶和桥,双连通分量,有向图的强连通分量)
一.dfs框架: vector<int>G[maxn]; //存图 int vis[maxn]; //节点访问标记 void dfs(int u) { vis[u] = ; PREVISI ...
随机推荐
- python脚本中selenium启动浏览器报错os.path.basename(self.path), self.start_error_message) selenium.common.excep
在python脚本中,使用selenium启动浏览器报错,原因是未安装浏览器驱动,报错内容如下: # -*- coding:utf-8 -*-from selenium import webdrive ...
- Aragorn's Story
A - Aragorn's Story 直接套 线段树+树剖 板子 代码: // Created by CAD on 2019/8/12. #include <bits/stdc++.h> ...
- MySQL中的exist与not exists
准备数据 我们先介绍下使用的3个数据表: student数据表: course数据表: sc数据表: EXISTS EXISTS代表存在量词∃.带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真 ...
- 笔记本电脑如何同时上内外网(通过usb外接网卡实现虚拟机连外网)
我们这里达成的方式不是内外网切换,而是真正意义上的同时上内网和外网 原理: 通过构建虚拟机,利用usb外接网卡(某宝某东都有售,价格在50大洋左右)使虚机连接外网,然后开启虚拟机的unity模式 准备 ...
- 套接字之 getsockname && getpeername
getsockname-获取本地地址:比如,在绑定的时候设置端口号为0由系统自动选择端口绑定,或者使用了INADDR_ANY通配所有地址的情况下,后面需要用到具体的地址和端口,就可以用getsockn ...
- Gradle 依赖
在开发中,我们经常使用compile,api,implementation引入库,这三种是有区别的. 1 api和compile api和compile关键字作用效果是一样的,使用时可以互相替换. 实 ...
- Molecular Dynamics
First]前处理 Second]运行MD Third]后处理 一.获得结构文件-来自实验数据或者某些化学软件工具 1]第一步: 获取并处理pdb文件 从Protein Data Bank下载小肽的p ...
- np.unique()对一维和二维数组去重
numpy.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)[source] 一 ...
- Python基本语法_控制流语句_if/while/for
目录 目录 前言 软件环境 If 语句 While循环 break continue for 循环 遍历String 遍历Tuple 遍历List 遍历Dictionary 最后 前言 控制流语句用于 ...
- django 通过模型类操作数据表(基础增删改查)
进入项目shell的命令: python manage.py shell 以下为在相互shell终端中演示的例子: 首先导入模型类:(from 应用名.models import 类名) from b ...