35pts求调
查看原帖
35pts求调
411141
alpharchmage楼主2024/11/9 16:46
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n = 0 , cnt = 0 , tot = 0 , ans = 0;
array<int , 1000010> head , dep , ok , dis , tmp , num;
array<pair<int , int> , 1000010> pre;
array<array<int , 3> , 1000010> dp;
struct Point{
	int pos;
	int val;
};
deque<int> q;
vector<Point> ring[1000010];
vector<int> ini[1000010];
struct Node{
	int to;
	int val;
	int nxt;
};
array<Node , 4000010> edge;
void new_line(int a , int b , int c)
{
	edge[++ cnt].to = b;
	edge[cnt].nxt = head[a];
	edge[cnt].val = c;
	head[a] = cnt;
	return;
}
void get_dis(int x , int fa , int id)
{
	for(int e = head[x];e;e = edge[e].nxt)
	{
		int to = edge[e].to;
		if(ok[to] || to == fa) continue;
		get_dis(to , x , id);
		if(dp[to][1] + edge[e].val > dp[x][1])
		{
			dp[x][2] = dp[x][1];
			dp[x][1] = dp[to][1] + edge[e].val;
		}
		else if(dp[to][1] + edge[e].val > dp[x][2]) dp[x][2] = dp[to][1] + edge[e].val; 
	}
	num[id] = max(num[id] , dp[x][1] + dp[x][2]);
	return;
}
void dfs(int x , int t)
{
	dep[x] = dep[pre[x].first] + 1;
	for(int e = head[x];e;e = edge[e].nxt)
	{
		int to = edge[e].to;
		int p = (t & 1 ? (t + 1) : (t - 1));
		if(e == p && t != -1) continue;
		if(!dep[to])
		{
			pre[to] = {x , edge[e].val};
			dfs(to , e);
		}
		else if(dep[to] < dep[x])
		{
			++ tot;
			int now = edge[e].val;
			for(int tmp = x;;tmp = pre[tmp].first)
			{
				ok[tmp] = true;
				ring[tot].push_back({tmp , 0});
				ini[tot].push_back(now);
				now += pre[tmp].second;
				if(tmp == to) break;
			}
			for(int i = 0;i < ring[tot].size();++ i)
			{
				get_dis(ring[tot][i].pos , 0 , tot);
				ring[tot][i].val = dp[ring[tot][i].pos][1];
			}
		}
	}
}
int solve(int x)
{
	while(!q.empty()) q.pop_front();
	int k = ring[x].size() , res = INT_MIN;
	for(int i = 0;i < k;++ i)
	{
		dis[i + 1] = dis[i + ring[x].size() + 1] = ring[x][i].val;
		tmp[i + 1] = ini[x][i];
		tmp[i + ring[x].size() + 1] = ini[x][i] + ini[x][k - 1];
	}
//	for(int i = 1;i <= 2 * k;++ i) cout << tmp[i] << ' ';
//	cout << endl;
	for(int i = 1;i <= 2 * k;++ i)
	{
		while(!q.empty() && q.front() <= i - k) q.pop_front();
		if(!q.empty())
		{
			res = max(res , dis[i] + dis[q.front()] + tmp[i] - tmp[q.front()]);
		}
		while(!q.empty() && dis[i] - i >= dis[q.back()] - q.back()) q.pop_back();
		q.push_back(i);
	}
	for(int i = 1;i <= 2 * k;++ i) dis[i] = tmp[i] = 0;
	res = max(res , num[x]);
	return res;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n;
	num.fill(LLONG_MIN);
	for(int i = 1;i <= n;++ i)
	{
		int x = 0 ,  y = 0;
		cin >> x >> y;
		new_line(i , x , y);
		new_line(x , i , y);
	}
	for(int i = 1;i <= n;++ i)
	{
		if(!dep[i])
		{
			dfs(i , -1);	
		}
	}
	for(int i = 1;i <= tot;++ i)
	{
		ans += solve(i);
	}
	cout << ans << endl;
	return 0;
}
2024/11/9 16:46
加载中...