Tarjan缩点割点(模板)
描述:https://www.luogu.com.cn/problem/P3387
给定一个 nn 个点 mm 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn=;
int n,m,p[maxn],dp[maxn];
struct edge{
int u,to,nxt;
}d[maxn*];int head[maxn*],cnt=;
void add(int u,int v){
d[cnt].u=u,d[cnt].to=v,d[cnt].nxt=head[u],head[u]=cnt++;
}
int dfn[maxn],low[maxn],id,stack[maxn],vis[maxn],top,sd[maxn];//为tarjan准备
void tarjan(int now)
{
dfn[now]=low[now]=++id;
stack[++top]=now,vis[now]=;
for(int i=head[now];i;i=d[i].nxt)
{
int w=d[i].to;
if(!dfn[w])
tarjan(w),low[now]=min(low[now],low[w]);
else if(vis[w])
low[now]=min(low[now],low[w]);
}
if(low[now]==dfn[now])
{
int temp;
while(temp=stack[top--])
{
sd[temp]=now;
vis[temp]=;
if(temp==now) break;
p[now]+=p[temp];//集中在now这个超级点上
}
}
}
int indug[maxn];
vector<int>vec[maxn];
int tuopu()
{
queue<int>q;
for(int i=;i<=n;i++) if(!indug[i]&&sd[i]==i) q.push(i),dp[i]=p[i];
while(!q.empty())
{
int now=q.front();q.pop();
for(int i=;i<vec[now].size();i++)
{
int w=vec[now][i];
dp[w]=max(dp[w],dp[now]+p[w]);
if(--indug[w]==) q.push(w);
}
}
int ans=;
for(int i=;i<=n;i++) ans=max(ans,dp[i]);
return ans;
}
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++) cin>>p[i];//读入点权
for(int i=;i<=m;i++)
{
int l,r;cin>>l>>r;
add(l,r);
}
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=;i<=m;i++)
{
int x=sd[d[i].u],y=sd[d[i].to];//看看两头是否是连通分量
if(x!=y)//不是就建边
vec[x].push_back(y),indug[y]++;
}
cout<<tuopu();
return ;
}
还有割点的
为什么(“low[v]>=dfn[u],此时u就是割点”)??
因为后面的点无法回到u点之前
u就把两个部分分开来了
#include <bits/stdc++.h>
using namespace std;
const int maxn=;
struct edge{
int nxt,to;
}d[maxn];
int n,m,id,cnt=,ttp;
int head[maxn],dfn[maxn],low[maxn],cut[maxn];
void add(int u,int v){
d[cnt].to=v,d[cnt].nxt=head[u],head[u]=cnt++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++id;
int child=;
for(int i=head[u];i;i=d[i].nxt)
{
int w=d[i].to;
if(!dfn[w])
{
tarjan(w,fa);
low[u]=min(low[u],low[w]);
if(low[w]>=dfn[u]&&u!=fa)//通过非非节点更新的low[w]
//因为在本连通块能回溯最多到dfn[u]
cut[u]=;
if(u==fa) child++;
}
low[u]=min(low[u],dfn[w]);
}
if(child>=&&u==fa) cut[u]=;
}
int main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int l,r;
cin>>l>>r;
add(l,r);add(r,l);
}
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i,i);
int ans=;
for(int i=;i<=n;i++)
if(cut[i]) ans++;
cout<<ans<<endl;
for(int i=;i<=n;i++)
if(cut[i])
cout<<i<<" ";
return ;
}
Tarjan缩点割点(模板)的更多相关文章
- tarjan 缩点(模板)
描述: 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 注:允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 思路: ...
- Tarjan缩点【模板】
#include <algorithm> #include <cstdio> #include <map> using namespace std; ); map& ...
- Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)
Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...
- tarjan求强连通分量+缩点+割点以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- Tarjan的缩点&&割点概述
What is Tarjan? Tarjan,是一种用来解决图的联通性的一种有效途径,它的一般俗称叫做:缩点.我们首先来设想一下: 如果我们有一个图,其中A,B,C构成一个环,那么我们在某种条件下,如 ...
- HDU4738 tarjan割边|割边、割点模板
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4738 坑点: 处理重边 图可能不连通,要输出0 若求出的结果是0,则要输出1,因为最少要派一个人 #inc ...
- Tarjan求强连通分量、求桥和割点模板
Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using n ...
- [模板]tarjan缩点+拓扑排序
题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先t ...
随机推荐
- alg-链表中有环
typedef struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {} }ListN ...
- split(resource,limit) 中limit 的含义
limit 参数控制模式应用的次数,因此影响结果数组的长度.如果该限制 n 大于 0,则模式将被最多应用 n - 1 次,数组的长度将不会大于 n,而且数组的最后项将包含超出最后匹配的定界符的所有输入 ...
- 【Java】 语言基础习题汇总 [1] 基础概念到数组
1 JDK JRE JVM 三种之间的关系,以及JDK JRE 包含的主要结构有哪些? JDK = JRE + 开发工具 javac.exe java.exe javadoc.exe等等 JRE = ...
- dubbo(三):负载均衡实现解析
dubbo作为分布式远程调用框架,要保证的点很多,比如:服务注册与发现.故障转移.高性能通信.负载均衡等等! 负载均衡的目的是为了特定场景下,能够将请求合理地平分到各服务实例上,以便发挥所有机器的叠加 ...
- 用python画出全球疫情趋势变化图
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:谦睿科技 PS:如有需要Python学习资料的小伙伴可以加点击下方链接 ...
- 美的PDF转换成Word转换器完全免费
下载地址:百度网盘提取码:02ap 安装破解步骤:先安装主程序,末尾是full结尾的,安装完成后不要打开软件,然后接着安装破解补丁,即可破解成功! 需要的老铁们直接拿去用吧,亲测好用!有配套的功能强大 ...
- python 进阶篇 函数装饰器和类装饰器
函数装饰器 简单装饰器 def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapp ...
- vue中解决时间在ios上显示NAN的问题
最近在用vue,遇到倒计时在ios上显示为NAN的问题. 因为做的是倒计时支付,思路是获取服务器时间和下单时间,再转成秒级时间戳做差值. 在网上找到说是ios 不支持例如2018-09-01 10:0 ...
- Java 多线程实现方式一:继承Thread类
java 通过继承Thread类实现多线程很多简单: 只需要重写run方法即可. 比如我们分三个线程去京东下载三张图片: 1.先写个下载类: 注意导入CommonsIO 包 public class ...
- WFS: postgresql(postgis)和shp文件查询效率对比
对GeoServer上的WFS的各种数据源查询效率感兴趣,做个测试.本次测试了Postgresql.geopackage.shp文件三种数据源的查询效率,无论是本机还是服务器环境,pg存储查询效率都比 ...