描述: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缩点割点(模板)的更多相关文章

  1. tarjan 缩点(模板)

    描述: 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 注:允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 思路: ...

  2. Tarjan缩点【模板】

    #include <algorithm> #include <cstdio> #include <map> using namespace std; ); map& ...

  3. Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)

    Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...

  4. tarjan求强连通分量+缩点+割点以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  5. tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明

    “tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄>   自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...

  6. Tarjan的缩点&&割点概述

    What is Tarjan? Tarjan,是一种用来解决图的联通性的一种有效途径,它的一般俗称叫做:缩点.我们首先来设想一下: 如果我们有一个图,其中A,B,C构成一个环,那么我们在某种条件下,如 ...

  7. HDU4738 tarjan割边|割边、割点模板

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4738 坑点: 处理重边 图可能不连通,要输出0 若求出的结果是0,则要输出1,因为最少要派一个人 #inc ...

  8. Tarjan求强连通分量、求桥和割点模板

    Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using n ...

  9. [模板]tarjan缩点+拓扑排序

    题目:给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次. 题目简述:先t ...

随机推荐

  1. Spring Cloud和eureka启动报错 解决版本依赖关系

    导读 An attempt was made to call a method that does not exist. The attempt was made from the following ...

  2. 【python系统学习14】类的继承与创新

    目录: 目录: [toc] 类的继承 子类和父类 继承的写法 继承示例 父类可以被无限个子类所继承 子类实例可调用父类属性和方法 类的始祖(根类) 根类 - object 实例归属判断 - isins ...

  3. Keepalived实现Nginx负载均衡高可用

    第一章:keepalived介绍 VRRP协议 目的就是为了解决静态路由单点故障问题的 第二章: keepalived工作原理 2.1 作为系统网络服务的高可用功能(failover) keepali ...

  4. 给学妹的 Java 学习路线

    大家好,这篇文章主要是讲解下如何自学 Java,这个问题有很多粉丝私信问过,今天又有直系学妹问我如何学习 Java? 我就以我的经历,总结下分享给大家,有不当指出或者有更好的方法建议也欢迎留言指出,大 ...

  5. Python中赋值、浅拷贝和深拷贝的区别

    前言文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http: ...

  6. C - Long Beautiful Integer codeforces 1269C 构造

    题解: 这里的m一定是等于n的,n为数最大为n个9,这n个9一定满足条件,根据题目意思,前k个一定是和原序列前k个相等,因此如果说我们构造出来的大于等于原序列,直接输出就可以了,否则,由于后m-k个一 ...

  7. D. Points in rectangle

    D. Points in rectangle 单点时限: 2.0 sec 内存限制: 512 MB 在二维平面中有一个矩形,它的四个坐标点分别为(0,a),(a,0),(n,n−a),(n−a,n). ...

  8. Linux下nginx自启动配置

    1.在linux系统的/etc/init.d/目录下创建nginx文件 vim /etc/init.d/nginx 在脚本中添加一下命令(内容主要参考官方文档) #!/bin/sh # # nginx ...

  9. Springboot:员工管理之公共页面提取 高亮显示(十(5))

    把顶部和左侧的公共代码分别放到header.html和left.html中 顶部代码:resources\templates\header.html 主内容展示: <!DOCTYPE html& ...

  10. Java的自动装箱

    JDK5的新特性自动装箱:把基本类型转换为包装类类型自动拆箱:把包装类类型转换为基本类型 注意一个小问题: 在使用时,Integer x = null;代码就会出现NullPointerExcepti ...