codeforces 1084 D. The Fair Nut and the Best Path(트리 dp)

2051 단어 dp
제목은 여기.
제목의 대의: 각 점에 권한이 있고 각 변에도 권한이 있다. 하나의 경로를 찾아서 점권과 감변권과 최대를 만들 수 있다. 답안도 단지 하나의 점으로 답을 출력할 수 있다.
사고방식: 트리 dpdp는 이 점에서 하위 노드까지의 최대치를 기록한다ans 답안을 기록한다
답안 업데이트와 전이 방정식 얻기;여기에서 ans를 먼저 업데이트해야 합니다. 왜냐하면 to 노드를 사용하여 이 노드를 업데이트하기 전에 ans 이전 방정식을 업데이트하면 to 노드가 업데이트된 후와 이전에 가장 큰 값을 얻을 수 있기 때문입니다.
ans=max(ans,dp[u]-now.se+dp[to]);
dp[u]=max(dp[u],a[u]-now.se+dp[to]);
#include
#define fi first
#define se second
#define FOR(a) for(int i=0;i#define sc(a) scanf("%d",&a)
#define show(a) cout<#define show2(a,b) cout<#define show3(a,b,c) cout<using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 3e5 + 10;
const ll mod = 1e9+7;
map<string, int>ml;
ll c[N], vis[N][10],  num[N], t, n, m, x, y, k, a[N];
char s[N];
ll ex, ey, cnt, ans, sum;
ll dist[N];
ll dp[N];
deque <int> q;
vector<P> v[N];
void dfs(int f,int u)
{
dp[u]=a[u];
ans=max(ans,dp[u]);
for(int i=0;i<v[u].size();i++)
{
P now=v[u][i];
int to=now.fi;
if(to==f) continue;
dfs(u,to);
ans=max(ans,dp[u]-now.se+dp[to]);
dp[u]=max(dp[u],a[u]-now.se+dp[to]);
}
}
int main()
{
ios::sync_with_stdio ( false );
cin.tie ( 0 );
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++)
{
cin>>x>>y>>k;
v[x].push_back(make_pair(y,k));
v[y].push_back(make_pair(x,k));
}
dfs(0,1);
cout<<ans<<endl;
}

좋은 웹페이지 즐겨찾기