P3387 【模板】缩点(Tarjan求强连通分量)
题目背景
缩点+DP
题目描述
给定一个 nnn 个点 mmm 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大。你只需要求出这个权值和。
允许多次经过一条边或者一个点,但是,重复经过的点,权值只计算一次。
输入格式
第一行两个正整数 n,mn,mn,m
第二行 nnn 个整数,依次代表点权
第三至 m+2m+2m+2 行,每行两个整数 u,vu,vu,v,表示一条 u→vu\rightarrow vu→v 的有向边。
输出格式
共一行,最大的点权之和。
输入输出样例
输入 #1
2 2 1 1 1 2 2 1
输出 #1
2
板子题因为脑瘫错误调了半天...
注意到题干描述,很容易看出是要缩点,跑一遍Tarjan后我们就得到了一个DAG,DAG有点类似树的结构,只需要从每个入度为0的点(有点类似树根)跑dfs就行了,记得记忆化。
#include <bits/stdc++.h> using namespace std; const int N = 10005; const int M = 100005; int ver[M],Next[M],head[N],dfn[N]={0},low[N]; int vc[M],nc[M],hc[N],tc=0; int sstack[N],ins[N],c[N]; int point[N],point_c[N]={0}; vector<int>scc[N]; int n,m,tot=0,num=0,top=0,cnt=0; int ans[N]={0}; void add(int x, int y) { ver[++tot]=y,Next[tot]=head[x],head[x]=tot; } void add_c(int x,int y) { vc[++tc]=y,nc[tc]=hc[x],hc[x]=tc; } void tarjan(int x) { dfn[x]=low[x]=++num; sstack[++top]=x,ins[x]=1; int i; for(i=head[x];i;i=Next[i]) { if(!dfn[ver[i]]) { tarjan(ver[i]); low[x]=min(low[x],low[ver[i]]); } else if(ins[ver[i]]) low[x]=min(low[x],dfn[ver[i]]); } if(dfn[x]==low[x]) { cnt++; int y; do { y=sstack[top--],ins[y]=0; c[y]=cnt,scc[cnt].push_back(y); }while(x!=y); } } void dfs(int x,int pre)//得用缩点后的新图 { int i; ans[x]=max(ans[x],ans[pre]+point_c[x]); for(i=hc[x];i;i=nc[i]) { if(vc[i]!=pre)dfs(vc[i],x); } } int main() { cin>>n>>m; int i,j,x; for(i=1;i<=n;i++)scanf("%d",&point[i]); for(i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); } for(i=1;i<=n;i++) { if(!dfn[i])tarjan(i); } int deg[N]={0}; for(x=1;x<=n;x++) { for(i=head[x];i;i=Next[i]) { int y=ver[i]; if(c[x]==c[y])continue; add_c(c[x],c[y]); deg[c[y]]++;//deg表示入度 别写成deg[y]++ } } for(i=1;i<=cnt;i++) { for(j=0;j<scc[i].size();j++) { point_c[i]+=point[scc[i][j]]; } } //新图是一个有向无环图 找入度为0的点 ans[0]=0; for(i=1;i<=cnt;i++) { if(deg[i]==0)//不能只从入度为0的点开始遍历 { dfs(i,0); } } int mmax=0; for(i=1;i<=cnt;i++) { mmax=max(mmax,ans[i]); } cout<<mmax<<endl; return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!