「SP14887」 GOODA
题意
给定一个 \(n\) 个点 \(m\) 条边的有向图,每个点都有点权,求一条从 \(S\) 到 \(E\) 的路径,使路径经过的点权值之和最大。
可以多次经过一条边或者一个点,但每个点的权值最多计算一次。
分析
和 P3387 很像。
对原图缩点后得到一张 DAG,然后在图上跑类似最短路,实际是拓扑的东西就可以了。
复杂度大概是 \(O(n)\)。
Code
#include<bits/stdc++.h> typedef long long ll; using namespace std; #define dbg(x) cout<<#x<<": "<<x<<"\n" // static char buf[100],*p1=buf,*p2=buf,obuf[100],*p3=obuf; // #define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,100,stdin),p1==p2)?EOF:*p1++ // #define putchar(x) (p3-obuf<100)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x) inline ll read(){ll x=0,f=1;char c=getchar();while(c<48||c>57){if(c==45)f=0;c=getchar();}while(c>47&&c<58)x=(x<<3)+(x<<1)+(c^48),c=getchar();return f?x:-x;} inline void write(ll x){if(!x){putchar(48);putchar('\n');return;}short top=0,s[40];if(x<0)x=-x,putchar(45);while(x)s[top++]=x%10^48,x/=10;while(top--)putchar(s[top]);putchar('\n');} mt19937_64 rnd(chrono::system_clock::now().time_since_epoch().count()); const ll mod=998244353,maxn=2e5+5,maxt=505; ll n,m,s,e,frm[maxn],to[maxn],a[maxn],dfn[maxn],low[maxn],tot,col[maxn],cnt,siz[maxn],f[maxn]; bool vis[maxn]; stack<ll>st; vector<ll>son[maxn]; inline void tarjan(ll u){ dfn[u]=low[u]=++tot,vis[u]=1,st.push(u); for(auto v:son[u]){ if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]); else if(vis[v])low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ ++cnt; while(st.top()!=u)col[st.top()]=cnt,siz[cnt]+=a[st.top()],vis[st.top()]=0,st.pop(); col[u]=cnt,siz[cnt]+=a[u],vis[u]=0,st.pop(); } } inline void dfs(ll u){ if(f[u])return; f[u]=siz[u]; ll mx=0; for(auto v:son[u]){ if(!f[v])dfs(v); mx=max(mx,f[v]); } f[u]+=mx; } inline void solve(){ n=read(),m=read(),s=read(),e=read(); for(ll i=1;i<=n;++i)a[i]=read(); for(ll i=1;i<=m;++i){ frm[i]=read(),to[i]=read(); son[frm[i]].push_back(to[i]); } for(ll i=1;i<=n;++i)if(!dfn[i])tarjan(i); for(ll i=1;i<=n;++i)son[i].clear(); for(ll i=1;i<=m;++i){ if(col[frm[i]]!=col[to[i]]){ son[col[frm[i]]].push_back(col[to[i]]); } } memset(vis,0,sizeof(vis)); queue<ll>q;q.push(col[s]),vis[col[s]]=1,f[col[s]]=siz[col[s]]; while(!q.empty()){ ll u=q.front();q.pop();vis[u]=0; for(auto v:son[u]){ f[v]=f[u]+siz[v]; if(!vis[v])vis[v]=1,q.push(v); } } write(f[col[e]]); } signed main(){ // freopen(".in","r",stdin); // freopen(".out","w",stdout); ll t=1; while(t--){ solve(); } // fwrite(obuf,p3-obuf,1,stdout); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】