标签:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 2589 | Accepted: 1382 |
Description
Input
Output
Sample Input
5 0 0 -2 0 1 1 1 0 1 0 -1 1 -1 0 1
Sample Output
2
Source
题意:就是要在一棵强连通的树中找一个权值最大强连通的子树
分析:dp[i][1] 如果选了该结点,那么它的子节点在选与不选中选权值大的 dp[i][1] = dp[i][1] + max(dp[i_son][1],dp[i_son][0]) i_son是i的所有子树
dp[i][0] 如果不选该结点,那么它的子节点有且只能选一个才能够保证强连通 dp[i][0] = max(dp[i][0],max(dp[i_son][1],dp[i_son][0]))
边只开了N WA了,,一定要记得是2*N ,还有就是math.h的fabs会报 CE ,还是用stdlib.h中的 abs吧
///dp[i][1] 如果选了该结点,那么它的子节点在选与不选中选权值大的 ///dp[i][0] 如果不选该结点,那么它的子节点有且只能选一个才能够保证强连通 #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #define N 1005 using namespace std; int dp[N][2]; ///dp[i][0]代表不选择i结点以i为根节点的子树能够获得最大的权, ///dp[i][1]代表选择i结点以i为根节点的子树能够获得最大的权 int head[N]; struct Edge { int u,v,next; } edge[2*N]; ///!!!!开两倍 void addEdge(int u,int v,int &k) { edge[k].u = u,edge[k].v = v; edge[k].next = head[u],head[u]=k++; } int vis[N]; void dfs(int u) { vis[u]=1; for(int k=head[u]; k!=-1; k=edge[k].next) { int v = edge[k].v; if(!vis[v]) { dfs(v); dp[u][1]+= max(dp[v][0],dp[v][1]); dp[u][0] = max(dp[u][0],max(dp[v][1],dp[v][0])); } } } int main() { int n; while(scanf("%d",&n)!=EOF) { memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); int x[N],y[N],w,tot=0; for(int i=1; i<=n; i++) { scanf("%d%d%d",&x[i],&y[i],&w); dp[i][1]=w; for(int j=1; j<i; j++) { if((abs(x[i]-x[j])+abs(y[i]-y[j]))==1) { addEdge(i,j,tot); addEdge(j,i,tot); } } } dfs(1);///随便选取一个根 printf("%d\n",max(dp[1][0],dp[1][1])); } }
标签:
原文地址:http://www.cnblogs.com/liyinggang/p/5414179.html