Modules(最小树形图)
生活随笔
收集整理的這篇文章主要介紹了
Modules(最小树形图)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:
Modules
描述? ? 蒜頭有一塊主板,為了提升其性能,可在主板上安置若干增強模塊。蒜頭有n個不同的增強模塊,增強模塊可以直接安置在主板上,也可以安置在已經直接或間接連接在主板上的其他增強模塊上。
? ? 每個增強模塊具有一個初始強化值,其中第i個模塊的初始強化值為Pi。在所有模塊安置完成后,每個模塊的最終強化值為其自身初始強化值及直接安置在其上的所有模塊的最終強化值之和。
? ? 除此之外,有m對模塊由于具有良好的契合度,在安置時可以獲得額外的強化值加成:將模塊Aj直接安置在模塊Bj上時,模塊Bj的強化值可以獲得Qj的額外加成。
? ? 主板的最終強化值為直接安置在主板上的所有模塊最終強化值之和,請合理安置模塊使得主板獲得最大的強化值,并輸出最大強化值。
輸入輸入第一行為一個整數T,表示一共有T組測試數據。
對于每組測試數據:
第一行為兩個整數n,m(1≤n≤3000,0≤m≤3000)。
第二行為n個整數Pi(1≤Pi≤109),數之間以單個空格間隔。
接下來m行中,第j行有三個整數Aj,Bj,Qj(1≤Aj,Bj≤n,Aj≠Bj,1≤Qj≤109)。
數據保證同一組(Aj,Bj)只出現一次。
對于每組測試數據:輸出一個整數表示主板的最大強化值。
樣例輸入1 1 3 4 1 2 4 3 1 8 3 2 16 2 1 32 1 2 64 樣例輸出1 87題意:
思路:可以發現所有的p最后都會加到答案上,然后那些邊要求不能有環,而且出度為1,把邊方向就是求最大樹形圖了,可以建一個虛根,然后向每個點連邊,跑朱劉算法就好了,這里的最大樹形圖一定存在(加了根之后邊數會變多,我數組開小了一直wa)
AC代碼:
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=3e3+10; LL ans=0; const LL inf=1e14; int n,m,vis[maxn],id[maxn],pre[maxn],cnt=0; LL in[maxn]; struct Edge {int u,v;LL cost; }edge[2*maxn]; inline void add_edge(int u,int v,LL w) {cnt++;edge[cnt].u=u;edge[cnt].v=v;edge[cnt].cost=w; } inline LL solve() {LL ret=0;int root=0;for(int i=1;i<=n;i++)add_edge(root,i,0);n=n+1;while(true){for(int i=0;i<n;i++)in[i]=-inf;for(int i=1;i<=cnt;i++){if(edge[i].cost>in[edge[i].v]&&edge[i].u!=edge[i].v){in[edge[i].v]=edge[i].cost;pre[edge[i].v]=edge[i].u;}}int cntnode=0;memset(id,-1,sizeof(id));memset(vis,-1,sizeof(vis));in[root]=0;for(int i=0;i<n;i++){ret=ret+in[i];int v=i;while(vis[v]!=i&&v!=root&&id[v]==-1){vis[v]=i;v=pre[v];}if(id[v]==-1&&v!=root){for(int u=pre[v];u!=v;u=pre[u])id[u]=cntnode;id[v]=cntnode++;}}if(cntnode==0)break;for(int i=0;i<n;i++){if(id[i]==-1)id[i]=cntnode++;}for(int i=1;i<=cnt;i++){int v=edge[i].v;edge[i].u=id[edge[i].u];edge[i].v=id[edge[i].v];if(edge[i].u!=edge[i].v){edge[i].cost-=in[v];}}n=cntnode;root=id[root];}return ret; } int main() {int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);cnt=0;ans=0;int u,v,w,x;for(int i=1;i<=n;i++)scanf("%d",&x),ans=ans+x;for(int i=1;i<=m;i++){scanf("%d%d%d",&u,&v,&w);add_edge(v,u,(LL)w);}printf("%lld\n",solve()+ans);}return 0; }
?
轉載于:https://www.cnblogs.com/zhangchengc919/p/6877991.html
總結
以上是生活随笔為你收集整理的Modules(最小树形图)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 5.18
- 下一篇: 第11讲++数据的基本查询