日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/10 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 894E Ralph and Mushrooms (强连通缩点+dp) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題意:一張有向圖,每條邊上都有wi個蘑菇,第i次經過這條邊能夠采到w-(i-1)*i/2個蘑菇,直到它為0。問最多能在這張圖上采多少個蘑菇。

分析:在一個強連通分量內,邊可以無限次地走直到該連通塊內蘑菇被采完為止,因此每個強連通分量內的結果是確定的。

設一條邊權值為w,最大走過次數為t,解一元二次方程得 t = (int)(1+sqrt(1+8w));則該邊對所在連通塊的貢獻為w*t - (t-1)*t*(t+1)/6。

而不在任何一個強連通分量內的邊,最多只能走一次。所以在縮點后的DAG上進行dp即可。

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn =1e6+5; struct Edge{int v,next;LL val; }edges[maxn],E[maxn]; int head[maxn],tot,H[maxn],tt; stack<int> S; int pre[maxn],low[maxn],sccno[maxn],dfn,scc_cnt; LL W[maxn]; LL dp[maxn]; void init() {tot = dfn = scc_cnt=tt=0;memset(H,-1,sizeof(H));memset(W,0,sizeof(W));memset(dp,0,sizeof(dp));memset(pre,0,sizeof(pre));memset(sccno,0,sizeof(sccno));memset(head,-1,sizeof(head)); }void AddEdge(int u,int v,LL val) {edges[tot] = (Edge){v,head[u],val};head[u] = tot++; }void Tarjan(int u) {int v;pre[u]=low[u]=++dfn;S.push(u);for(int i=head[u];~i;i=edges[i].next){v= edges[i].v;if(!pre[v]){Tarjan(v);low[u]=min(low[u],low[v]);}else if(!sccno[v]){low[u]=min(low[u],pre[v]);}}if(pre[u]==low[u]){int x;++scc_cnt;for(;;){x = S.top();S.pop();sccno[x]=scc_cnt;if(x==u)break;}} }void nAddEdge(int u,int v,LL w) {E[tt] = (Edge){v,H[u],w};H[u] = tt++; }LL dfs(int u) {if(dp[u]) return dp[u];for(int i=H[u];~i;i=E[i].next){int v = E[i].v;dp[u] = max(dp[u],dfs(v)+E[i].val);}dp[u]+=W[u];return dp[u]; }int main() {#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);freopen("out.txt","w",stdout);#endifint N,M; while(scanf("%d%d",&N,&M)==2){init();int st,u,v; LL w;while(M--){scanf("%d%d%lld",&u,&v,&w);AddEdge(u,v,w);}scanf("%d",&st);for(int i=1;i<=N;++i){if(!pre[i]){Tarjan(i);}}for(int u =1;u<=N;++u){for(int i =head[u];~i;i = edges[i].next){v = edges[i].v;LL w = edges[i].val;if(sccno[u]!=sccno[v]){nAddEdge(sccno[u],sccno[v],w);}else{int t = (int)(1+sqrt(1+8*w))/2;W[sccno[u]] += (LL)t*w - (LL)(t-1)*t*(t+1)/6;}}}for(int i=1;i<=scc_cnt;++i){if(!dp[i]){dfs(i);}}printf("%lld\n",dp[sccno[st]]);}return 0; }

?

轉載于:https://www.cnblogs.com/xiuwenli/p/9494938.html

總結

以上是生活随笔為你收集整理的CodeForces - 894E Ralph and Mushrooms (强连通缩点+dp)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。