CF894E Ralph and Mushrooms

Posted cjoiershiina-mashiro

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF894E Ralph and Mushrooms相关的知识,希望对你有一定的参考价值。

题目
一眼题。
缩点然后dp。
注意一下计算一条边经过无限次可以获得多少价值这个东西要用到平方和公式。
(sumlimits_{i=1}^ni^2=frac{i(i+1)(2i+1)}6)

#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define pi pair<int,int>
using namespace std;
int read(){int x;scanf("%d",&x);return x;}
int min(int a,int b){return a<b? a:b;}
ll max(ll a,ll b){return a>b? a:b;}
const int N=1000007;
vector<int>G[N];vector<pi>E[N];
int Time,cnt,dfn[N],low[N],bel[N],stk[N],top,vis[N];ll val[N],f[N];
struct edge{int u,v,w;}e[N];
ll cal(int x){int n=(sqrt(1+x*8)-1)/2;return (n+1ll)*x-1ll*n*(n+1)*(n+2)/6;}
void tarjan(int u)
{
    dfn[u]=low[u]=++Time,vis[stk[++top]=u]=1;
    for(int v:G[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(low[u]==dfn[u]) for(++cnt;stk[top+1]^u;--top) bel[stk[top]]=cnt,vis[stk[top]]=0;
}
int main()
{
    int n=read(),m=read(),s;
    for(int i=1;i<=m;++i) e[i]=(edge){read(),read(),read()},G[e[i].u].pb(e[i].v);
    tarjan(s=read());
    for(int i=1;i<=m;++i)
    if(bel[e[i].u]&&bel[e[i].v])
        if(bel[e[i].u]==bel[e[i].v]) val[bel[e[i].u]]+=cal(e[i].w);
        else E[bel[e[i].u]].pb(pi(bel[e[i].v],e[i].w));
    for(int u=1;u<=cnt;++u)
    {
    for(auto[v,w]:E[u]) f[u]=max(f[u],f[v]+w);
    f[u]+=val[u];
    }
    printf("%lld",f[bel[s]]);
}

以上是关于CF894E Ralph and Mushrooms的主要内容,如果未能解决你的问题,请参考以下文章

[2019CSP-S赛前训练][CF894E] Ralph and Mushrooms

CodeForces - 894E Ralph and Mushrooms (强连通缩点+dp)

Codeforces 894 B Ralph And His Magic Field

codeforces 894B - Ralph And His Magic Field - [数学题]

Codeforces894E.Ralph and Mushrooms Tarjan缩点+DP

[codeforces 894 E] Ralph and Mushrooms 解题报告 (SCC+拓扑排序+DP)