题目:
分析:最近公共祖先过程中修改即可。
代码:自己写的上面修改,超时:
#include<bits/stdc++.h>
using namespace std;
int m1,m2,n;
vector<vector<int> > vv;
int A1[100005];
int A2[100005];
int A3[100005];
string ss;
void f1(int c,int c1)
{
A3[c]=1;
A2[c]=c1;
for(int i=0;i<vv[c].size();i++)
{
if(A3[vv[c][i]]==1) continue;
A1[vv[c][i]]=c;
f1(vv[c][i],1+c1);
}
}
int main()
{
cin>>m1>>m2;
cin>>ss;
vector<int> v;
for(int i=0;i<=m1;i++) vv.push_back(v);
for(int i=1;i<m1;i++)
{
int a,b;
cin>>a>>b;
vv[a].push_back(b);
vv[b].push_back(a);
}
memset(A3,0,sizeof(A3));
f1(1,1);
int x1,x2;
char cc;
for(int i=0;i<m2;i++)
{
cin>>x1>>x2;
cin>>cc;
if(ss[x1-1]==cc||ss[x2-1]==cc) {
cout<<1;
continue;
}
int ok=0;
if(A2[x1]>A2[x2])
{
int t=-A2[x2]+A2[x1];
for(int k=0;k<t;k++)
{
x1=A1[x1];
if(ss[x1-1]==cc)
{
ok=1;
break;
}
}
if(ok)
{
cout<<1;
continue;
}
}
else if(A2[x1]<A2[x2])
{
int t=A2[x2]-A2[x1];
for(int k=0;k<t;k++)
{
x2=A1[x2];
if(ss[x2-1]==cc)
{
ok=1;
break;
}
}
if(ok)
{
cout<<1;
continue;
}
}
while(1)
{
if(x1==x2)
{
if(ss[x1-1]==cc)
{
ok=1;
}
break;
}
x2=A1[x2];x1=A1[x1];
if(ss[x1-1]==cc)
{
ok=1;
}
if(ss[x2-1]==cc)
{
ok=1;
}
if(ok)
{
break;
}
}
if(ok) cout<<1;
else cout<<0;
}
}
时隔半个月再次看到这个题,思路已经是很广的了,我的思路是:
根据最近公共祖先的思想
先由任意一点建立树。
然后标记每一个结点的层数。
目标结点先走到一层,然后一起走。
在此过程中,如果发现开心,就可以提前结束了。
嗯,和之前想的一样,又写了一遍。
题解nb:什么情况才不开心,走过去都是同一种颜色,而且不是开心颜色。
那么,就来个并查集就Ok啦。
再来一遍并查集。
#include<bits/stdc++.h>
using namespace std;
int m,n;
string s;
int A[100005];
int find(int x)
{
if(A[x]==x) return x;
A[x]=find(A[x]);
return A[x];
}
int main()
{
cin>>m>>n;
cin>>s;
for(int i=0;i<=m;i++)
{
A[i]=i;
}
for(int i=1;i<m;i++)
{
int a,b;
cin>>a>>b;
if(s[a-1]==s[b-1])
{
if(find(a)!=find(b)){
A[find(a)]=find(b);
}
}
}
for(int i=0;i<n;i++)
{
int a,b;
char c;
cin>>a>>b>>c;
if(find(a)==find(b)&&c!=s[a-1]) cout<<0;
else cout<<1;
}
}
这两点又打错了!!!,需要再次深入理解一下啊,非常容易错。