Codeforces GYM 100962J: Jimi Hendrix 题解

显然树形dp

dp1[i]表示以i为根的子树中从左往右最多能匹配多少位,dp2[i]表示以i为根的子树中从右往左最多能匹配多少位

dp数组同时记录这个max是从哪个叶子跑上来的

dp1[i]和dp2[i]能很简单的从i的孩子那里统计得到

然后对于任意i,只要dp1[i]+dp2[i]>=m 就说明有答案

要注意从左往右和从右往左要从不同的孩子那里获得,所以烦一点的话可能要写一个second_max

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <utility>
#include <cctype>
#include <algorithm>
#include <bitset>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <cmath>
#define LL long long
#define LB long double
#define x first
#define y second
#define Pair pair<int,int>
#define pb push_back
#define pf push_front
#define mp make_pair
#define LOWBIT(x) x & (-x)
using namespace std;

const int MOD=1e9+7;
const LL LINF=2e16;
const int INF=2e9;
const int magic=348;
const double eps=1e-10;

inline int getint()
{
	char ch;int res;bool f;
	while (!isdigit(ch=getchar()) && ch!='-') {}
	if (ch=='-') f=false,res=0; else f=true,res=ch-'0';
	while (isdigit(ch=getchar())) res=res*10+ch-'0';
	return f?res:-res;
}

vector<Pair> v[500048];
int n,len;
char type[5],s[500048];
Pair dp1[500048],dp2[500048];
Pair dp11[500048],dp22[500048];
bool ans_exist;Pair ans;

struct node
{
	int val;
	int ind;
	int from;
};

void dfs(int cur,int father)
{
	int i,y;
	if ((int(v[cur].size())==1 && father!=-1) || int(v[cur].size())==0)
	{
		dp1[cur]=dp2[cur]=mp(0,cur);
		return;
	}
	dp1[cur]=dp2[cur]=mp(-1,cur);
	for (i=0;i<int(v[cur].size());i++)
		if (v[cur][i].x!=father)
		{
			y=v[cur][i].x;
			dfs(y,cur);
			if (ans_exist) return;
			int tmp1=((s[dp1[y].x+1]-'a'+1==v[cur][i].y)?1:0),tmp2=((s[len-dp2[y].x]-'a'+1==v[cur][i].y)?1:0);
			if (dp1[y].x+tmp1>dp1[cur].x) dp1[cur]=mp(dp1[y].x+tmp1,dp1[y].y);
			if (dp2[y].x+tmp2>dp2[cur].x) dp2[cur]=mp(dp2[y].x+tmp2,dp2[y].y);
		}
	if ((v[cur].size()==2 && father!=-1) || (v[cur].size()==1 && father==-1))
	{
		if (dp1[cur].x>=len)
		{
			ans_exist=true;
			ans=mp(dp1[cur].y,cur);
			return;
		}
		if (dp2[cur].x>=len)
		{
			ans_exist=true;
			ans=mp(cur,dp2[cur].y);
			return;
		}
		return;
	}
	node fmax1,smax1,fmax2,smax2;
	fmax1.val=smax1.val=fmax2.val=smax2.val=-1;
	for (i=0;i<v[cur].size();i++)
		if (v[cur][i].x!=father)
		{
			y=v[cur][i].x;
			int tmp=(s[dp1[y].x+1]-'a'+1==v[cur][i].y?1:0);
			if (dp1[y].x+tmp>fmax1.val)
			{
				smax1=fmax1;
				fmax1.val=dp1[y].x+tmp;
				fmax1.ind=dp1[y].y;
				fmax1.from=y;
			}
			else
			{
				if (dp1[y].x+tmp>smax1.val)
				{
					smax1.val=dp1[y].x+tmp;
					smax1.ind=dp1[y].y;
					smax1.from=y;
				}
			}
			tmp=s[len-dp2[y].x]-'a'+1==v[cur][i].y?1:0;
			if (dp2[y].x+tmp>fmax2.val)
			{
				smax2=fmax2;
				fmax2.val=dp2[y].x+tmp;
				fmax2.ind=dp2[y].y;
				fmax2.from=y;
			}
			else
			{
				if (dp2[y].x+tmp>smax2.val)
				{
					smax2.val=dp2[y].x+tmp;
					smax2.ind=dp2[y].y;
					smax2.from=y;
				}
			}
		}
	if (fmax1.from!=fmax2.from)
	{
		if (fmax1.val+fmax2.val>=len)
		{
			ans_exist=true;
			ans=mp(fmax1.ind,fmax2.ind);
		}
		return;
	}
	if (fmax1.val+smax2.val>=len)
	{
		ans_exist=true;
		ans=mp(fmax1.ind,smax2.ind);
		return;
	}
	if (smax1.val+fmax2.val>=len)
	{
		ans_exist=true;
		ans=mp(smax1.ind,fmax2.ind);
		return;
	}
}

int main ()
{
	int i,x,y;
	n=getint();len=getint();
	for (i=1;i<=n-1;i++)
	{
		scanf("%d%d%s",&x,&y,type+1);
		v[x].pb(mp(y,type[1]-'a'+1));
		v[y].pb(mp(x,type[1]-'a'+1));
	}
	scanf("%s",s+1);
	ans_exist=false;ans=mp(-1,-1);dfs(1,-1);
	printf("%d %d\n",ans.x,ans.y);
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您提供的链接是Codeforces的一个问题,问题编号为104377。Codeforces是一个知名的在线编程竞赛平台,经常举办各种编程比赛和训练。GymCodeforces的一个扩展包,用于组织私人比赛和训练。您提供的链接指向了一个问题的页面,但具体的问题内容和描述无法通过链接获取。如果您有具体的问题或需要了解关于Codeforces Gym的更多信息,请提供更详细的信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [http://codeforces.com/gym/100623/attachments E题](https://blog.csdn.net/weixin_30820077/article/details/99723867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [http://codeforces.com/gym/100623/attachments H题](https://blog.csdn.net/weixin_38166726/article/details/99723856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [CodeforcesPP:Codeforces扩展包](https://download.csdn.net/download/weixin_42101164/18409501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值