//poj 1192 最优连通子集 (树型DP) /* 题意:给定一个平面整点集,点与点间在|x1-x2| + |y1-y2| = 1时相邻,且形成的图没有回路, 每个点有一个可正可负的权值,求最大权和连通子图。 题解:树型DP,dp[i][0]表示以i为根的子树上不包括i的最大权和,dp[i][1]表示包括i的最大权和。 */ #include <iostream> #include <algorithm> #include <cmath> #include <vector> using namespace std; const int inf = 1<<28; int n,m; struct Point { int x,y,c; }p[1010]; vector<int> con[1010]; int dp[1010][2],mark[1010]; void dfs(int v) { mark[v]=1; dp[v][0]=0,dp[v][1]=p[v].c; int j; for (int i=0;i<con[v].size();i++) if (!mark[con[v][i]]) { j=con[v][i]; dfs(j); dp[v][0]=max(dp[v][0],max(dp[j][0],dp[j][1])); if (dp[j][1]>0) dp[v][1]+=dp[j][1]; } } int main() { scanf("%d",&n); for (int i=0;i<n;i++) scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].c); for (int i=0;i<n;i++) for (int j=i+1;j<n;j++) if (abs(p[i].x-p[j].x)+abs(p[i].y-p[j].y)==1) { con[i].push_back(j); con[j].push_back(i); } dfs(0); printf("%d/n",max(dp[0][0],dp[0][1])); system("pause"); return 0; }