1 条题解

  • 2
    @ 2026-4-24 8:40:12

    第一种合法和第二种合法情况并不冲突

    dp[x][0/1/2]dp[x][0/1/2]为以x为根的子树已合法,并且x所在连通块状态是 没有红色/只有0个绿色/只有1个绿色 需要删除的最短长度 直接分讨即可

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    #define big __int128
    #define pii pair<int,int>
    #define F first
    #define S second
    #define mkp make_pair 
    const int mod=1e9+7,inf=1e16;
    int T,n;
    struct node{
    	int v,nxt,w;
    }e[601000];
    int tot,head[301000];
    void add(int x,int y,int z){
    	e[++tot]={y,head[x],z};
    	head[x]=tot;
    }
    int col[301000],tc[114514];
    int dp[301000][3];
    void dfs(int x,int baba){
    	int flag=0;
    	dp[x][0]=dp[x][1]=dp[x][2]=inf;
    	for(int i=head[x];i;i=e[i].nxt){
    		int y=e[i].v;
    		if(y==baba) continue;
    		dfs(y,x);
    	}
    	if(col[x]==1){
    		int sum=0,minn=inf;
    		for(int i=head[x];i;i=e[i].nxt){
    			int y=e[i].v,z=e[i].w;
    			if(y==baba) continue;
    			int val=min(dp[y][1],min(dp[y][0],dp[y][2])+z);
    			minn=min(minn,dp[y][2]-val);
    			sum+=val;
    		}
    		dp[x][1]=min(dp[x][1],sum);
    		dp[x][2]=min(dp[x][2],sum+minn);
    	}else if(col[x]==2){
    		int sum1=0,sum2=0;
    		for(int i=head[x];i;i=e[i].nxt){
    			int y=e[i].v,z=e[i].w;
    			if(y==baba) continue;
    			sum1=sum1+min(dp[y][0],min(dp[y][1],dp[y][2])+z);
    			sum2=sum2+min(dp[y][1],min(dp[y][0],dp[y][2])+z);
    		}
    		dp[x][0]=min(dp[x][0],sum1);
    		dp[x][2]=min(dp[x][2],sum2);
    	}else{
    		int sum=0,minn=inf,sum1=0;
    		for(int i=head[x];i;i=e[i].nxt){
    			int y=e[i].v,z=e[i].w;
    			if(y==baba) continue;
    			int val=min(dp[y][1],min(dp[y][0],dp[y][2])+z);
    			sum1=sum1+min(dp[y][0],min(dp[y][1],dp[y][2])+z);
    			minn=min(minn,dp[y][2]-val);
    			sum+=val;
    		}
    		dp[x][0]=min(dp[x][0],sum1);
    		dp[x][1]=min(dp[x][1],sum);
    		dp[x][2]=min(dp[x][2],sum+minn);
    	}
    //	printf("%d -- %d %d %d  ---\n",x,dp[x][0],dp[x][1],dp[x][2]);
    }
    signed main(){
    	tc['R']=1;tc['G']=2,tc['B']=3;
    	ios::sync_with_stdio(0);
    	cin.tie(0);
    //	freopen("ex.in","r",stdin);
    //	freopen("my.out","w",stdout);
    //	system("fc my.out ex.out");return 0;
    	cin>>T;
    	while(T--){
    		cin>>n;
    		for(int i=1;i<=n;i++){
    			char c;
    			cin>>c;
    			col[i]=tc[c];
    		}
    		for(int i=1;i<n;i++){
    			int x,y,z;
    			cin>>x>>y>>z;
    			add(x,y,z);
    			add(y,x,z);
    		}
    		dfs(1,0);
    		cout<<min(dp[1][0],min(dp[1][1],dp[1][2]))<<"\n";
    		tot=0;
    		for(int i=1;i<=n;i++){
    			head[i]=0;
    		}
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    701
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    6
    已通过
    3
    上传者