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 ...
随机推荐
- AtomicInteger的并发处理
AtomicInteger的并发处理 博客分类: Effective Java JDK1.5之后的java.util.concurrent.atomic包里,多了一批原子处理类.主要用于在高并发环 ...
- springboot项目war包部署及出现的问题Failed to bind properties under 'mybatis.configuration.mapped-statements[0].
1.修改pom文件 修改打包方式 为war: 添加tomcat使用范围,provided的意思即在发布的时候有外部提供,内置的tomcat就不会打包进去 <groupId>com.scho ...
- 004-流程控制-C语言笔记
004-流程控制-C语言笔记 学习目标 1.[掌握]关系运算符和关系表达式 2.[掌握]逻辑运算符和逻辑表达式 3.[掌握]运算符的优先级和结合性 4.[掌握]if-else if-else结构的使用 ...
- 第九节:os、sys、json、pickle、shelve模块
OS模块: os.getcwd()获取当前路径os.chdir()改变目录os.curdir返回当前目录os.pardir()父目录os.makedirs('a/b/c')创建多层目录os.remov ...
- JUC强大的辅助类讲解--->>>CountDownLatchDemo (减少计数)
原理: CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,这些线程会阻塞.其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞), ...
- util.Date与sql.Date的异同以及相互转换
Java中有两个Date类 一个是java.util.Date通常情况下用它获取当前时间或构造时间 另一个是java.sql.Date是针对SQL语句使用的,它只包含日期而没有时间部分 两个类型的时间 ...
- Sprint 3 : oxford project API 尝试
本次Sprint我们大家主要在调研和尝试阶段,主要是对photo experience 中的语音接口部分进行相应的调研和分析. 工作进度: 1. 图像界面设计兆阳和敏龙的工作进一步推进,除去之前介绍的 ...
- Salesforce LWC学习(十六) Validity 在form中的使用浅谈
本篇参考: https://developer.salesforce.com/docs/component-library/bundle/lightning-input/documentation h ...
- 杂记三 · CSP-2019-The first step
update:我终于懂得衰亡的民族之所以沉默的缘由了. 初赛Day -7 虽然我是第一次参加初赛而且到现在为止我还没见过初赛题但我一点也不慌! 真的!一点!也不慌! 初赛Day 1 早上和可s爱b j ...
- 支付宝开源非侵入式 Android 自动化测试工具 Soloπ
Soloπ(SoloPi)是支付宝开源的一个无线化.非侵入式的Android自动化测试工具,公测版拥有录制回放.性能测试.一机多控三项主要功能,能为测试开发人员节省宝贵时间. 本文是SoloPi团队关 ...