tarjan 缩点(模板)
描述:
给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
注:允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
思路:
tarjan 的模板之一——缩点。先利用 tarjan 出图中的强连通分量及大小(点的权值),然后遍历所有点,重新构图(←重点),根据 topo DP一下,就可得出图中最大的权值和。
标程:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<stack>
#include<vector>
#include<queue>
#include<deque>
#include<map>
#include<set>
using namespace std;
#define maxn 1000005
int n,m,cnt1,num,top,cnt2;//cnt1 作原图的前向星,cnt2 作新图的
int ins[maxn],head[maxn],nu[maxn],dfn[maxn],low[maxn];//nu 用来去除重边(重构图用),ins 记录强连通分量的大小
int st[maxn],co[maxn];//栈只为了表示此时是否有父子关系,co判断该点是否在栈中
int h[maxn],in[maxn],dis[maxn];//h相当于新图前向星的head,in统计点的入度,dis记录权值和(in,dis都做topo排序用)
int ans=;//统计答案
struct hh
{
int to,next,from;//from,to有可以分别记录边的起点和终点
}t1[maxn],t2[maxn];//t1原图,t2新图
inline int read()
{
int kr=,xs=;
char ls;
ls=getchar();
while(!isdigit(ls))
{
if(!(ls^))
kr=-;
ls=getchar();
}
while(isdigit(ls))
{
xs=(xs<<)+(xs<<)+(ls^);
ls=getchar();
}
return xs*kr;
}
inline void add(int x,int y)
{
t1[++cnt1].next=head[x];
t1[cnt1].from=x;
t1[cnt1].to=y;
head[x]=cnt1;
}//存原图
inline void tarjan(int x)
{
low[x]=dfn[x]=++num;
st[++top]=x;co[x]=;
for (int i=head[x];i;i=t1[i].next)
{
int v=t1[i].to;
if(!dfn[v])
{
tarjan(v);
low[x]=min(low[x],low[v]);
}
else if(co[v])
{
low[x]=min(low[x],low[v]);
}
}
if (dfn[x]==low[x])
{
int y;
while(y=st[top])
{
nu[y]=x;//表示:可以从x直接到达y(单向)
co[y]=;//y出栈(记录清除)
if(x==y) break;
ins[x]+=ins[y];//合并两个强连通分量
--top;
}
--top;
}
}//日常操作
inline void topo()
{
queue <int> q;
int tot=;
for (int i=;i<=n;i++)
if (nu[i]==i&&!in[i])//该点自己到达自己,且入度为0,表示为一个被缩为一点的强连通分量(且为起始点)
{
q.push(i);
dis[i]=ins[i];
}
while (!q.empty())//依次取出所有的起点(入度为0的点)
{
int k=q.front();q.pop();
for (int i=h[k];i;i=t2[i].next)//遍历可以到达的点
{
int v=t2[i].to;
dis[v]=max(dis[v],dis[k]+ins[v]);//更新答案
in[v]--;//入度--
if(in[v]==) q.push(v);//减到这个点入度为0,扔进队列,下次再取出作为起点
}
}
for (int i=;i<=n;i++)
ans=max(ans,dis[i]);//更新最终答案
}
int main()
{
n=read();m=read();
for (int i=;i<=n;i++)
ins[i]=read();//初始每个点认为是一个强连通分量(假装是)
for (int i=;i<=m;i++)
{
int u,v;
u=read();v=read();
add(u,v);
}
for (int i=;i<=n;i++)
if(!dfn[i])
tarjan(i);
for (int i=;i<=m;i++)
{
int x=nu[t1[i].from],y=nu[t1[i].to];
if (x!=y)//←可以去除重边
{
t2[++cnt2].next=h[x];
t2[cnt2].to=y;
t2[cnt2].from=x;
h[x]=cnt2;//重构新图
in[y]++;
}
}
topo();//topo 排序
printf("%d",ans);//输出
return ;
}
tarjan 缩点(模板)的更多相关文章
- LuoGu-P2863牛的舞会The Cow Prom[tarjan 缩点模板]
传送门:https://www.luogu.org/problemnew/show/P2863 思路:tarjan模板题,之前会的tarjan,一直想学缩点到底是什么操作,发现就是把同组的放在一个数组 ...
- 【洛谷P5008 逛庭院】tarjan缩点+贪心
既然没有题解,那么我就来提供给一份. -- 首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪 ...
- [模板]tarjan缩点+拓扑排序
题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先t ...
- 洛谷 P2194 HXY烧情侣【Tarjan缩点】 分析+题解代码
洛谷 P2194 HXY烧情侣[Tarjan缩点] 分析+题解代码 题目描述: 众所周知,HXY已经加入了FFF团.现在她要开始喜(sang)闻(xin)乐(bing)见(kuang)地烧情侣了.这里 ...
- BZOJ2199[Usaco2011 Jan]奶牛议会——2-SAT+tarjan缩点
题目描述 由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会.议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 <= M ...
- Tarjan&&缩点简析
由于昨天写计蒜客初赛的一道题,看出了是缩点,但一时忘记了另外一个叫什么s...的算法怎么写了,话说我为什么没有回去翻一下自己的blog然后今天就去学了更实用也更强力的Tarjan Tarjan的思想其 ...
- POJ 1236 Network of Schools Tarjan缩点
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22729 Accepted: 89 ...
- HDU1269(有向图缩点模板题)
迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 初涉tarjan缩点
tarjan缩点:口胡过好多题,不过从来没写过…… 什么是缩点 tarjan和Kosaraju.Gabow算法一样,是为了求有向图中的强连通分量.因为有向图中大多数情况下会有环存在,而有环是一个不甚好 ...
- POJ-3352 Road Construction,tarjan缩点求边双连通!
Road Construction 本来不想做这个题,下午总结的时候发现自己花了一周的时间学连通图却连什么是边双连通不清楚,于是百度了一下相关内容,原来就是一个点到另一个至少有两条不同的路. 题意:给 ...
随机推荐
- HDU 1207 汉诺塔II (递推)
经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘.上 ...
- Logstash进程杀不掉
由于ELK磁盘不足,对磁盘进行扩容,重启服务器,重启之后发现自动起来了一个logstash进程,PID一直变,无法杀掉,极其耗费CPU logstash 是通过rpm方式安装的,版本是6.2.2 解决 ...
- Python读写docx文件
Python读写word文档有现成的库可以处理.我这里采用 python-docx.可以用pip install python-docx安装一下. 这里说一句,ppt和excel也有类似的库哦,而且是 ...
- sqlalchemy 小试
# -*- coding: utf-8 -*- from sqlalchemy import Column, String, create_engine,ForeignKey,Text,INTEGER ...
- Docker学习笔记之了解 Docker 的核心组成
0x00 概述 在掌握 Docker 的一些背景知识后,我们还不得不花费一节的篇幅来简单介绍有关 Docker 核心的一些知识.当然,大家不要觉得有“核心”这类的词,我们就要在这一节中深入 Docke ...
- Golang接口简单了解
在Golang中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口. package main import "fmt" type Animal interface ...
- memset与malloc性能测试(转)
前一段跟同事聊项目组已有的一些工具,同事讲里面有太多的malloc与memset,对性能的影响比较大,因此今天就在自己的机器上测试了这两个函数,不多说,上数据.测试环境:2.2GHZ.2G内存mems ...
- Tree Implementation with Python
Tree Implementation with Python List of List 代码如下: def binary_tree(val): return [val, [], []] def in ...
- Kali系列之Hydra/Medusa mysql密码爆破
hydra hydra -L /home/chenglee/zidian/user.txt -P /home/chenglee/zidian/wordlist.TXT 192.168.137.133 ...
- python3 logging模块
很多程序都有记录日志的需求,并且日志包含的信息有正常的程序访问日志还可能有错误,警告等信息输出,python的logging模块提供了标准的日志接口,可以通过它存储各种格式的日志,日志级别等级:cri ...