TLE求助
查看原帖
TLE求助
993065
nnn233楼主2023/12/6 13:29
#include<bits/stdc++.h>
using namespace std;
long long const M=1e9+7;
long long cnt,n,m,k,r,fir[100005],dp[100005][3],node[100005],ti[100005],g;
struct EDGE{
	int u,v,next,w;
}e[200005];
void add(int u,int v){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].next=fir[u];
	fir[u]=cnt;
}
inline int read()
{
	int s=0;char c=getchar();
	while(!isdigit(c))  c=getchar();
	while(isdigit(c))  s=(s<<3)+(s<<1)+(c^48),c=getchar();
	return s;
}
void dfs(int u,int fa){
	dp[u][1]+=node[u];
	dp[u][2]+=node[u];
	long long max1=0,max2=0,max3=0,maxi=0;
	for(int i=fir[u];i;i=e[i].next){
		if(e[i].v!=fa){
			dfs(e[i].v,u);
			dp[u][0]+=dp[e[i].v][0];
			dp[u][1]+=dp[e[i].v][0];
			dp[u][2]+=dp[e[i].v][0];
			if(dp[e[i].v][2]>dp[e[i].v][0]&&dp[e[i].v][2]-dp[e[i].v][0]>dp[maxi][2]-dp[maxi][0])maxi=e[i].v;
			if((node[e[i].v]>node[max2]||max2==0)&&ti[e[i].v]==3)max2=e[i].v;
			if(node[max2]>node[max3]||max3==0)swap(max2,max3);
			if(node[e[i].v]>max1)max1=node[e[i].v];
		}
	}
	if(maxi!=max3)dp[u][0]+=max(dp[maxi][2]-dp[maxi][0]+node[max3],max1),dp[u][1]+=max(dp[maxi][2]-dp[maxi][0]+node[max3],max1);
	else dp[u][0]+=max(dp[maxi][2]-dp[maxi][0]+node[max2],max1),dp[u][1]+=max(dp[maxi][2]-dp[maxi][0]+node[max2],max1);
}
int main(){
	g=read();
	while(g--){
		memset(e,0,sizeof(e));
		memset(fir,0,sizeof(fir));
		memset(dp,0,sizeof(dp));
		cnt=0;
		n=read();
		for(int i=1;i<=n;++i)
			node[i]=read();
		for(int i=1;i<=n;++i)
			ti[i]=read();
		for(int i=2;i<=n;++i){
			int u,v;
			u=read(),v=read();
			add(u,v);add(v,u);
		}
		dfs(1,0);
		cout<<dp[1][1]<<"\n";
	}
	return 0;
}
/*
dp[i][0]为在节点i晶蝶已经消失后来到节点i最多可取得的晶蝶数量
dp[i][1]为在节点i晶蝶未消失前来到节点i最多可取得的晶蝶数量
dp[i][2]为在节点i晶蝶未消失前来到节点i但不要节点i所有直接子节点晶蝶最多可取得的晶蝶数量 
 
到达每个节点,有两种方案
(1) 选择一个节点,去继续遍历该节点。 
(2) 选择一个节点,拿到该节点晶蝶后立刻返回,再去另一个t==3的节点遍历
*/

理论计算时间复杂度是O(n),但是提交后TLE,跑了3.03s

2023/12/6 13:29
加载中...