POJ1192最优连通子串----树形dp

中文题面,目的很明显,把相邻的两个点看成是两个点之间有一条边,就能当成树形dp来做了。

用一遍dfs可以找出最大的子树权值和。

#include<iostream>
#include<vector>
#include<queue>
#include<string.h>
#include<stdio.h>
#include<map>
using namespace std;
#define p pair<int,int>
map<p,int> mp,pd;
int a[2010][2010],ans=0;
int dfs(int x,int y)
{
    //cout<<x<<" "<<y<<endl;
    int d;
    if(mp[p(x,y)]==999) d=0;
    else d=mp[p(x,y)];
    //cout<<d<<" ";
    pd[p(x,y)]=1;
    if(mp[p(x+1,y)]==0||pd[p(x+1,y)]!=0) ;
    else d+=dfs(x+1,y);
    if(mp[p(x,y+1)]==0||pd[p(x,y+1)]!=0) ;
    else d+=dfs(x,y+1);
    if(mp[p(x-1,y)]==0||pd[p(x-1,y)]!=0) ;
    else d+=dfs(x-1,y);
    if(mp[p(x,y-1)]==0||pd[p(x,y-1)]!=0) ;
    else d+=dfs(x,y-1);
    ans=max(ans,d);
    //cout<<d<<endl;
    if(d>0) return d;
    else return 0;
}
int main()
{
    int n,i,j,k,l,x,y,z;
    cin>>n;
    for(i=0;i<n;i++)
    {
        cin>>x>>y>>z;
        if(z==0) z=999;
        mp[p(x,y)]=z; //用于标记该点是否存在,为了避免0的干扰,对权值为0的点特判 
        pd[p(x,y)]=0;//标记这个点(x,y)是否遍历到过 
    }
    dfs(x,y);
    cout<<ans<<endl;
}

猜你喜欢

转载自www.cnblogs.com/wsblm/p/10732182.html