[2018.10.18 T1] 艾奇摘蘋果
阿新 • • 發佈:2018-11-09
暫無連結
艾奇摘蘋果
【問題描述】
艾奇在遙遠的美洲大陸有一片蘋果樹森林。
聽上去非常不錯的是,蘋果森林每年收成都還不錯。
艾奇摘蘋果的方式非常有趣,由於蘋果樹太高,她常直接折斷樹枝來獲得一大堆(整棵子樹)的蘋果。
艾奇也不想把蘋果樹破壞的太狠,畢竟蘋果樹也不是隻結一年的蘋果。所以她對於一棵樹,至多會折斷一根樹枝。
艾奇不像過去的某魯姓大師,她並沒有那個力氣倒拔蘋果樹,因為一棵樹的根是埋在土裡的。所以她並不能獲得整棵樹的蘋果。
眾所周知,美洲大陸龍捲風賊多。龍捲風既然能摧毀停車場,那麼吹翻一片蘋果森林應該不是什麼難事。所以艾奇養了一些小機器人給艾奇預警龍捲風。
艾奇把這些小機器人放在花上,這樣一來小機器人就能吸收樹的養分工作,但是這也導致了這朵花不能結果。
如果你折斷了一根樹枝,小機器人就會因為沒有養分而狂躁,它們只吃原本和它們屬於同一棵樹上被摘下來的蘋果。如果這些蘋果不夠吃,它們就會把艾奇吃掉。
樹林有點大,艾奇想知道,照她這種收果實的方法,在自己不被吃掉的情況下,至多能收穫多少蘋果呢?
【輸入格式】
輸入檔名為
。
第一行兩個整數
分別表示這片森林的節點樹和樹枝數量(就是邊的數量)。我們預設一棵樹的根就是這棵樹中編號最小的節點。
接下來
個整數。
如果該整數為正,那麼表示這個節點結蘋果的數量。
如果該整數為負,那麼表示這個節點養了一個小機器人,它被摘下來要吃的
果子數量。
對於一棵樹的根節點,這個節點的權值可以忽略。
接下來
行,每行兩個整數
表示
和
在樹上有邊相連。
【輸出格式】
輸出檔名為
。
一行一個整數,表示艾奇至多能收穫多少蘋果。
【輸入樣例 1】
詳見
【輸出樣例 1】
詳見
【資料範圍】
題解
求一棵樹中的最大子樹,把所有樹的最大子樹加到一起。
程式碼
略微卡常
#include<bits/stdc++.h>
using namespace std;
const int M=1e6+5;
int val[M],vis[M],head[M],nxt[M<<1],to[M<<1],n,m,cnt,r,f;
long long ans,sum[M],mx;
char c;
void add(int f,int t){nxt[++cnt]=head[f],head[f]=cnt,to[cnt]=t;}
int read()
{
for(r=0,f=1;!isdigit(c);c=getchar())if(c=='-')f=-1;
for(;isdigit(c);c=getchar())r=(r<<1)+(r<<3)+c-'0';
return r*f;
}
void dfs(int v){vis[v]=1,sum[v]=val[v];for(int i=head[v];i;i=nxt[i])if(!vis[to[i]])dfs(to[i]),sum[v]+=sum[to[i]],mx=max(mx,sum[to[i]]);}
void in()
{
n=read(),m=read();
for(int i=1;i<=n;++i)val[i]=read();
for(int i=1,a,b;i<=m;++i)a=read(),b=read(),add(a,b),add(b,a);
}
void ac(){for(int i=1;i<=n;++i)if(!vis[i])mx=0,dfs(i),ans+=mx;printf("%lld",ans);}
int main(){in(),ac();}