其他分享
首页 > 其他分享> > 做题记录 Luogu P4381

做题记录 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