ACM: Long Live the Queen - 树上的DP
/*/ 题意: 有N个村庄,每个村庄有一个权值,有n-1条路,将村庄连起来,然后选取这些路中的一个联通图,权值最大。 整个图都被联通,找其中权值最大的子联通块。 树状DP。 代码风格学了某个学长的写了个结构体,真刺激。。
AC代码: /*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include"algorithm" #include"iostream" #include"cstring" #include"cstdlib" #include"cstdio" #include"string" #include"vector" #include"queue" #include"cmath" using namespace std; typedef long long LL ; #define memset(x,y) memset(x,y,sizeof(x)) #define memcpy(x,y) memcpy(x,y,sizeof(x)) #define FK(x) cout<<"["<<x<<"]\n" #define bigfor(x) for(LL qq=1;qq<= T ;qq++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int MX = 16666; struct Treedp { struct Edge { int v,nxt; } E[MX<<1]; int Head[MX],erear; bool vis[MX]; int dp[MX]; int INF=-1e9-1e5; void init() { erear=0; memset (E,0); memset (vis,0); memset (Head,-1); } void add( int u, int v) { E[erear].v=v; E[erear].nxt=Head[u]; Head[u]=erear++; } int run( int u) { vis[u]=1; for ( int i=Head[u]; ~i; i=E[i].nxt) { int v=E[i].v; if (!vis[v]) { dp[u]+=max(0,run(v)); } } return dp[u]; } void print( int n) { for ( int i=1; i<=n; i++) cout<<dp[i]<< " " ; puts ( "" ); } }; Treedp tdp; int main() { int n,l,r; scanf ( "%d" ,&n); tdp.init(); for ( int i=1; i<=n; i++) { scanf ( "%d" ,&tdp.dp[i]); } for ( int i=1; i<n; i++) { scanf ( "%d%d" ,&l,&r); tdp.add(l,r); tdp.add(r,l); } int maxx=-1e9-1000000; tdp.run(1); for ( int i=1; i<=n; i++) { maxx=max(maxx,tdp.dp[i]); } // tdp.print(n); printf ( "%d\n" ,maxx); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步