这道题应该算是并查集的小变形 ,我做完之后,一直tle,这下个我正纠结了,看一下别人的代码,发现合并很重要,节省很多时间,不用每次都回溯追了老远,譬如a[1]=3,a[3]=2直接变成a[1]=2这样成了很多时间 ,给自己的代码小改一下,A了
#include<iostream>
using namespace std;
int a[20005];
int w[20005];
int cou;
int ask(int x)
{
if(a[x]!=x)
{
ask(a[x]);//用于回溯到顶点!!!!由顶点向回加,因为最后w[x]记录答案
w[x]+=w[a[x]];//将路径值加一起
a[x]=ask(a[x]); //很主要,将路径合并,譬如a[1]=3,a[3]=2直接变成a[1]=2这样成了很多时间
}
return a[x];
}
int main()
{
int cases,n;
cin>>cases;
int temp;
char m;
int x,y;
while(cases--)
{
for(int i=0;i<20005;i++)
{
a[i]=i;
w[i]=0;
}
cou=0;
cin>>temp;
while(cin>>m,m!='O')
{
if(m=='E')
{
cin>>x;
ask(x);
cout<<w[x]<<endl;
}
if(m=='I')
{
cin>>x>>y;
a[x]=y;
w[x]=abs(x-y)%1000;//初始化
}
}
}
return 0;
}