悬关求解:为什么不能调换预处理操作和统计答案操作
查看原帖
悬关求解:为什么不能调换预处理操作和统计答案操作
1125291
ZMQ_Ink6556楼主2024/11/19 09:13

RT,用小号关。

完整代码

错误代码(没开 long long):

#include<bits/stdc++.h>
using namespace std;
int T , n , a[100005] , t[100005] , dp0[100005] , dp1[100005];
vector<int> mp[100005];
bool vis[100005];
inline void dfs(int p , int fa)
{
	if(vis[p])
	{
		return;
	}
	vis[p] = 1;
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		dfs(mp[p][i] , p);
	}
//	dp0 = 丢根拿子
//	dp1 = 丢子拿根
	int cnt = 0 , p1 = -1 , q1 = -1000000007 , q2 = -1000000007;
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		cnt += dp0[mp[p][i]]; 
	}
	dp1[p] = cnt + a[p];
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		dp0[p] = max(dp0[p] , cnt + a[mp[p][i]]);
	}
	if(mp[p].size() < 2)
	{
		return;
	}
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		if(dp1[mp[p][i]] - dp0[mp[p][i]] > q1)
		{
			q2 = q1;
			q1 = dp1[mp[p][i]] - dp0[mp[p][i]];
			p1 = i;
		}
		else if(dp1[mp[p][i]] - dp0[mp[p][i]] > q2)
		{
			q2 = dp1[mp[p][i]] - dp0[mp[p][i]];
		}
	}
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		if(t[mp[p][i]] == 3)
		{
			if(i == p1)
			{
				dp0[p] = max(dp0[p] , cnt + q2 + a[i]);
			}
			else
			{
				dp0[p] = max(dp0[p] , cnt + q1 + a[i]);
			}
		}
	}
	return;
}
inline void clean()
{
	for(int i = 1 ; i <= n ; i++)
	{
		mp[i].clear();
		vis[i] = dp0[i] = dp1[i] = 0;
	}
	return;
}
int main()
{
	ios::sync_with_stdio(0);
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--)
	{
		cin >> n;
		clean();
		for(int i = 1 ; i <= n ; i++)
		{
			cin >> a[i];
		}
		for(int i = 1 ; i <= n ; i++)
		{
			cin >> t[i];
		}
		for(int i = 1 ; i < n ; i++)
		{
			int u , v;
			cin >> u >> v;
			mp[u].push_back(v);
			mp[v].push_back(u);
		}
		dfs(1 , 1);
		cout << dp0[1] + a[1] << '\n';
	}
	return 0;
}

正确代码(没开 long long):

#include<bits/stdc++.h>
using namespace std;
int T , n , a[100005] , t[100005] , dp0[100005] , dp1[100005];
vector<int> mp[100005];
bool vis[100005];
inline void dfs(int p , int fa)
{
	if(vis[p])
	{
		return;
	}
	vis[p] = 1;
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		dfs(mp[p][i] , p);
	}
//	dp0 = 丢根拿子
//	dp1 = 丢子拿根
	int cnt = 0 , p1 = -1 , q1 = -1000000007 , q2 = -1000000007;
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		cnt += dp0[mp[p][i]]; 
	}
	dp1[p] = cnt + a[p];
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		dp0[p] = max(dp0[p] , cnt + a[mp[p][i]]);
	}
	if(mp[p].size() < 2)
	{
		return;
	}
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa || t[mp[p][i]] < 3)
		{
			continue;
		}
		if(a[mp[p][i]] > q1)
		{
			q2 = q1;
			q1 = a[mp[p][i]];
			p1 = i;
		}
		else if(a[mp[p][i]] > q2)
		{
			q2 = a[mp[p][i]];
		}
	}
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		if(i == p1)
		{
			dp0[p] = max(dp0[p] , cnt + q2 + dp1[mp[p][i]] - dp0[mp[p][i]]);
		}
		else
		{
			dp0[p] = max(dp0[p] , cnt + q1 + dp1[mp[p][i]] - dp0[mp[p][i]]);
		}
	}
	return;
}
inline void clean()
{
	for(int i = 1 ; i <= n ; i++)
	{
		mp[i].clear();
		vis[i] = dp0[i] = dp1[i] = 0;
	}
	return;
}
int main()
{
	ios::sync_with_stdio(0);
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> T;
	while(T--)
	{
		cin >> n;
		clean();
		for(int i = 1 ; i <= n ; i++)
		{
			cin >> a[i];
		}
		for(int i = 1 ; i <= n ; i++)
		{
			cin >> t[i];
		}
		for(int i = 1 ; i < n ; i++)
		{
			int u , v;
			cin >> u >> v;
			mp[u].push_back(v);
			mp[v].push_back(u);
		}
		dfs(1 , 1);
		cout << dp0[1] + a[1] << '\n';
	}
	return 0;
}

区别部分

错误的:

	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		if(dp1[mp[p][i]] - dp0[mp[p][i]] > q1)
		{
			q2 = q1;
			q1 = dp1[mp[p][i]] - dp0[mp[p][i]];
			p1 = i;
		}
		else if(dp1[mp[p][i]] - dp0[mp[p][i]] > q2)
		{
			q2 = dp1[mp[p][i]] - dp0[mp[p][i]];
		}
	}
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		if(t[mp[p][i]] == 3)
		{
			if(i == p1)
			{
				dp0[p] = max(dp0[p] , cnt + q2 + a[i]);
			}
			else
			{
				dp0[p] = max(dp0[p] , cnt + q1 + a[i]);
			}
		}
	}

正确的:

	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa || t[mp[p][i]] < 3)
		{
			continue;
		}
		if(a[mp[p][i]] > q1)
		{
			q2 = q1;
			q1 = a[mp[p][i]];
			p1 = i;
		}
		else if(a[mp[p][i]] > q2)
		{
			q2 = a[mp[p][i]];
		}
	}
	for(int i = 0 ; i < mp[p].size() ; i++)
	{
		if(mp[p][i] == fa)
		{
			continue;
		}
		if(i == p1)
		{
			dp0[p] = max(dp0[p] , cnt + q2 + dp1[mp[p][i]] - dp0[mp[p][i]]);
		}
		else
		{
			dp0[p] = max(dp0[p] , cnt + q1 + dp1[mp[p][i]] - dp0[mp[p][i]]);
		}
	}

翻了一遍题解区,和这篇思路比较像,只是错误代码预处理 f(j,1)f(j,0)f(j , 1) - f(j , 0),正确代码预处理 aka_k

请问预处理 f(j,1)f(j,0)f(j , 1) - f(j , 0) 错在哪里了,求解答。

2024/11/19 09:13
加载中...