做题记录 Luogu P4381
作者:互联网
P4381 [IOI2008] Island - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
基环树 DP。以后会重写。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 1000005
queue<int> q;
int n, t[N], w[N], d[N], f[N], g[N], ans;
int dfs(int x)
{
int st = x, m1 = f[x], m2 = f[x], pre = w[x], ret1 = g[x], ret2 = -0x7fffffffffffffff;
x = t[x];
while(x != st)
{
d[x] = 0;
ret1 = max(ret1, max(f[x] + pre + m1, g[x]));
ret2 = max(ret2, f[x] - pre + m2);
m1 = max(m1, f[x] - pre);
m2 = max(m2, f[x] + pre);
pre += w[x];
x = t[x];
}
return max(ret1, ret2 + pre);
}
signed main()
{
scanf("%lld", &n);
for(int i = 1; i <= n; i++)
{
scanf("%lld%lld", &t[i], &w[i]);
d[t[i]]++;
}
for(int i = 1; i <= n; i++)
{
if(!d[i])
{
q.push(i);
}
}
while(!q.empty())
{
int x = q.front();
q.pop();
int tmp = f[x] + w[x];
g[t[x]] = max(g[t[x]], max(f[t[x]] + tmp, g[x]));
f[t[x]] = max(f[t[x]], tmp);
if(!(--d[t[x]]))
{
q.push(t[x]);
}
}
for(int i = 1; i <= n; i++)
{
if(d[i])
{
ans += dfs(i);
}
}
printf("%lld", ans);
return 0;
}
标签:pre,记录,int,Luogu,m2,ret2,m1,max,P4381 来源: https://www.cnblogs.com/fanypcd/p/15032198.html