Tarjan&&缩点简析
由于昨天写计蒜客初赛的一道题,看出了是缩点,但一时忘记了另外一个叫什么s...的算法怎么写了,话说我为什么没有回去翻一下自己的blog然后今天就去学了更实用也更强力的Tarjan
Tarjan的思想其实很简单,就是用时间戳(讲得真TM流弊,其实就是DFS访问到的次序)和栈来搞一下
关于Tarjan的写法,我自己也不是很讲得来,大家可以看一下这篇blog
这里讲一下如何用Tarjan来进行缩点
令我们求出的col[i]表示原图中第i个点是哪个强连通分量中的,则我们可以建出新图,方式如下
for (i=1;i<=n;++i)
for (j=head[i];j!=-1;j=e[j].next)
if (col[i]!=col[e[j].to]) add(col[i],col[e[j].to]);
很玄学?但是它就是正确的,然后我们就得到了缩过点的新图
像有这里有一道模板题:Luogu P3387 【模板】缩点
题意很简单,我们先Tarjan缩点,缩完的点的点权就是它这个强连通分量中的所有点的点权和
然后就是一个DAG(有向无环图)了,我们DP,记搜,拓扑排序都可以
这里我还是习惯性的写了BFS的topo
CODE
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e4+5,M=1e5+5;
struct edge
{
int to,next;
}e[M],ne[M];
int n,m,head[N],nhead[N],a[N],v[N],dfn[N],low[N],stack[N],col[N],dis[N],q[N],ru[N],top,cnt,x,y,tot,sum;
bool vis[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
}
inline void nadd(int x,int y)
{
ne[++cnt].to=y; ne[cnt].next=nhead[x]; nhead[x]=cnt;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline void Tarjan(int now)
{
dfn[now]=low[now]=++tot;
stack[++top]=now; vis[now]=1;
for (register int i=head[now];i!=-1;i=e[i].next)
if (!dfn[e[i].to])
{
Tarjan(e[i].to);
low[now]=min(low[now],low[e[i].to]);
} else
{
if (vis[e[i].to]) low[now]=min(low[now],dfn[e[i].to]);
}
if (dfn[now]==low[now])
{
col[now]=++sum;
v[sum]+=a[now]; vis[now]=0;
while (now!=stack[top])
{
col[stack[top]]=sum;
v[sum]+=a[stack[top]]; vis[stack[top--]]=0;
} --top;
}
}
inline int topo(void)
{
memset(dis,0,sizeof(dis));
register int i; int ans=0;
int H=0,T=0;
for (i=1;i<=sum;++i)
if (!ru[i]) q[++T]=i,dis[i]=v[i],ans=max(dis[i],ans);
while (H<T)
{
int now=q[++H];
for (i=nhead[now];i!=-1;i=ne[i].next)
{
dis[ne[i].to]=max(dis[ne[i].to],dis[now]+v[ne[i].to]);
ans=max(ans,dis[ne[i].to]);
if (!(--ru[ne[i].to])) q[++T]=ne[i].to;
}
}
return ans;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i,j;
memset(head,-1,sizeof(head));
memset(e,-1,sizeof(e));
read(n); read(m);
for (i=1;i<=n;++i)
read(a[i]);
for (i=1;i<=m;++i)
read(x),read(y),add(x,y);
for (i=1;i<=n;++i)
if (!dfn[i]) Tarjan(i);
memset(nhead,-1,sizeof(head));
memset(ne,-1,sizeof(e)); cnt=0;
for (i=1;i<=n;++i)
for (j=head[i];j!=-1;j=e[j].next)
if (col[i]!=col[e[j].to]) nadd(col[i],col[e[j].to]),++ru[col[e[j].to]];
printf("%d",topo());
return 0;
}
Tarjan&&缩点简析的更多相关文章
- 简析.NET Core 以及与 .NET Framework的关系
简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...
- 简析 .NET Core 构成体系
简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...
- hihoCoder 1185 连通性·三(Tarjan缩点+暴力DFS)
#1185 : 连通性·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 暑假到了!!小Hi和小Ho为了体验生活,来到了住在大草原的约翰家.今天一大早,约翰因为有事要出 ...
- POJ 1236 Network of Schools(Tarjan缩点)
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16806 Accepted: 66 ...
- King's Quest —— POJ1904(ZOJ2470)Tarjan缩点
King's Quest Time Limit: 15000MS Memory Limit: 65536K Case Time Limit: 2000MS Description Once upon ...
- RecycleView + CardView 控件简析
今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...
- 【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率
2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1638 Solved: 433[Submit][Statu ...
- 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP
1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 787 Solved: 318[Submit][Stat ...
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...
随机推荐
- 【Redis】Redis学习(六) Redis 基本运维
Redis的单机搭建,主从搭建,Sentinal搭建,以及Redis集群搭建的步骤参照前面的文章.现在来说一下Redis的基本运维,毕竟如果一切正常是最好的,但是当出现问题不能使用的时候,准确定位问题 ...
- react native 第一次下载app的欢迎页+每次启动app的启动页设计
欢迎各位同学加入: React-Native群:397885169 大前端群:544587175 大神超多,热情无私帮助解决各种问题. 我想我写的这篇博文可以帮助到很多人,接下来要分享的东西,对app ...
- MySQL 命令行操作集合
1.导入数据库 ) 登录 mysql -uroot -p Enter password: 2) 创建数据库create database pluto_0; 3)导入 source /var/www/m ...
- 从零自学Java-5.使用条件测试进行判断
1.使用if语句进行最基本的条件测试:2.测试一个值大于还是小于另一个值:3.测试两个值是否相等:4.使用与if语句对应的else语句:5.组合多个条件测试:6.使用switch语句进行复杂的条件测试 ...
- 使用 Visual Studio Team Services 和 IIS 创建持续集成管道
若要将应用程序开发的生成.测试和部署阶段自动化,可以使用持续集成和部署 (CI/CD) 管道. 本教程介绍如何在 Azure 中使用 Visual Studio Team Services 和 Win ...
- 购物商城学习--第三讲(tomcat插件启动web工程)
此处提到的tomcat插件即maven工程集成的tomcat插件,可以在添加maven的tomcat插件之后,在本地通过脚本或者命令行方式运行web工程,tomcat插件启动只需要修改一个端口即可,非 ...
- MySQL客户端连接方式
MySQL连接方式MySQL除了最常见的TCP连接方式外,还提供SOCKET(LINUX默认连接方式).PIPE和SHARED MEMORY连接方式.各连接方式的服务器.客户端启动选项,及连接默认值见 ...
- CentOS配置rsyslog Serve
CentOS6配置rsyslog Server: vi /etc/rsyslog.conf: #启用如下tcp支持: $ModLoad imtcp $InputTCPServerRun 514 #添加 ...
- [IDEA_2] IDEA 问题合集
1. IDEA 通过 Maven 导入的依赖包下面存在红色波浪线 问题描述: 创建的 Maven Project 在添加相关依赖后自动下载,自动添加的依赖包的下面存在红色波浪线,在使用过程中存在问题, ...
- 使用ubuntu过程中遇到的问题汇总
使用ubuntu过程中遇到的问题汇总 1.使用图形界面设置免密码登录之后,改回密码登陆失效 解决方案: https://askubuntu.com/questions/211084/how-do-i- ...