原题链接: 202312-3 树上搜索
代码如下:(可能命名有些问题,但耐心读一读吧)
#include<iostream>
#include <stdlib.h>
using namespace std;
struct node{
int num;
long long food;//权重
long long w;//差值
int h;//是否移除
node** jk;
int body;
};
class tree{
long long beginall;//总权重
long long changeall;//动态总权重
int n;//编号
long long minw;
node* pp;
int alln;
long long* er;
int* yu;
node* now;
long long cv;//占总权值
public:
void ert(){
cv=0;
changeall=beginall;
n=-1;
minw=-1;
rebuild(pp);
}
void rebuild(node* s){
s->h=0;
for(int i=0;i<s->body;i++){
node** p=s->jk;
rebuild(*(p+i));
}
}
void createtree(int a,long long* op,int* gh){
long long all=0;
for(int i=0;i<a;i++){
all=all+*(op+i);
}
beginall=all;
changeall=beginall;
n=-1;
minw=-1;
alln=a;
er=op;
yu=gh;
cv=0;
pp=build(1);
}
node* build(int g){
node* s=new node;
s->num=g;
s->food=*(er+g-1);
s->w=-1;
s->h=0;
int ccall=0;
for(int i=0;i<alln-1;i++){
int b=*(yu+i);
if(b==g){ccall++;}
}
s->body=ccall;
if(s->body>0){
s->jk=new node*[s->body];
int io=0;
for(int i=0;i<alln-1;i++){
int b=*(yu+i);
if(b==g){
*(s->jk+io)=build(i+2);
io++;
}
}
}
return s;
}
int sdf(node* s,int x){
if(s->h==0&&s->num==x){
return 1;
}
if(s->h==0&&s->num!=x){
int qwe=0;
for(int i=0;i<s->body;i++){
node** p=s->jk;
if(sdf(*(p+i),x)==1){
qwe=1;
break;
}
}
return qwe;
}
if(s->h==1){
return 0;
}
}
void show(int x){
node* cp=pp;
while(true){
select(cp);
cout<<n<<" ";
int ui=sdf(now,x);
if(ui==1){cp=now;changeall=0;change(cp);n=-1;minw=-1;}
else{action(now);n=-1;minw=-1;}
number(cp);
if(cv==1){cv=0;cout<<endl;break;}
cv=0;
}
}
void change(node* s){
if(s->h==0){
changeall=changeall+s->food;
for(int i=0;i<s->body;i++){
node** p=s->jk;
change(*(p+i));
}
}
}
void action(node* s){
s->h=1;
changeall=changeall-s->food;
for(int i=0;i<s->body;i++){
node** p=s->jk;
action(*(p+i));
}
}
void number(node* s){
if(s->h==0){cv++;
for(int i=0;i<s->body;i++){
node** p=s->jk;
node* cer=*(p+i);
if(cer->h==0){
cv++;break;
}
}
}
}
long long getw(node* s){
if(s->h==0){
long long allnow=s->food;
if(s->body==0){s->w=abs(changeall-allnow-allnow);return allnow;}
for(int i=0;i<s->body;i++){
node** p=s->jk;
allnow=allnow+getw(*(p+i));
}
s->w=abs(changeall-allnow-allnow);
return allnow;
}
else{return 0;}
}
void select(node* s){
getw(s);
selectnow(s);
}
void selectnow(node* s){
if(s->h==0){
if(minw==-1&&n==-1){
n=s->num;
minw=s->w;
now=s;
}
else{
if(s->w<minw){
n=s->num;
minw=s->w;
now=s;
}
if(s->w==minw&&s->num<n){
n=s->num;
minw=s->w;
now=s;
}
}
for(int i=0;i<s->body;i++){
node** p=s->jk;
selectnow(*(p+i));
}
}
}
};
int main(){
int n,m;
cin>>n>>m;
long long* p=new long long[n];
int* cc=new int[n-1];
int* df=new int[m];
for(int i=0;i<n;i++){
long long b;
cin>>b;
*(p+i)=b;
}
for(int i=0;i<n-1;i++){
int b;
cin>>b;
*(cc+i)=b;
}
for(int i=0;i<m;i++){
int b;
cin>>b;
*(df+i)=b;
}
tree* tr=new tree;
tr->createtree(n,p,cc);
for(int i=0;i<m;i++){
tr->show(*(df+i));
tr->ert();
}
return 0;
}
真的很想知道哪里错了!!!拜谢!
---------------------------------------------------------------------------------------(分割线)
好吧,事实上,有一个逻辑错误,有一个离谱错误(找了2,3天了,在没发稿之前就在找)
逻辑错误:(action函数有误,会导致changeall多减,加个if就好)
void action(node* s){
if(s->h==0){
s->h=1;
changeall=changeall-s->food;
for(int i=0;i<s->body;i++){
node** p=s->jk;
action(*(p+i));
}
}
}
改后如下:
然后,重点来了,<stdlib.h>中abs()求绝对值不对long long有效?!!好吧,本来想省点事。。。
好吧,用if-else吧。
long long getw(node* s){
if(s->h==0){
long long allnow=s->food;
if(s->body==0){
long long cvbn=changeall-allnow-allnow;
if(cvbn>=0){
s->w=cvbn;
}
else{
s->w=cvbn*-1;
}
return allnow;
}
for(int i=0;i<s->body;i++){
node** p=s->jk;
allnow=allnow+getw(*(p+i));
}
long long cvbn=changeall-allnow-allnow;
if(cvbn>=0){
s->w=cvbn;
}
else{
s->w=cvbn*-1;
}
return allnow;
}
else{return 0;}
}
于是:(不放心,试了两遍)
nice!!!
完整代码如下:
#include<iostream>
using namespace std;
struct node{
int num;
long long food;//权重
long long w;//差值
int h;//是否移除
node** jk;
int body;
};
class tree{
long long beginall;//总权重
long long changeall;//动态总权重
int n;//编号
long long minw;
node* pp;
int alln;
long long* er;
int* yu;
node* now;
long long cv;
public:
void ert(){
cv=0;
changeall=beginall;
n=-1;
minw=-1;
rebuild(pp);
}
void rebuild(node* s){
s->h=0;
for(int i=0;i<s->body;i++){
node** p=s->jk;
rebuild(*(p+i));
}
}
void createtree(int a,long long* op,int* gh){
long long all=0;
for(int i=0;i<a;i++){
all=all+*(op+i);
}
beginall=all;
changeall=beginall;
n=-1;
minw=-1;
alln=a;
er=op;
yu=gh;
cv=0;
pp=build(1);
}
node* build(int g){
node* s=new node;
s->num=g;
s->food=*(er+g-1);
s->w=-1;
s->h=0;
int ccall=0;
for(int i=0;i<alln-1;i++){
int b=*(yu+i);
if(b==g){ccall++;}
}
s->body=ccall;
if(s->body>0){
s->jk=new node*[s->body];
int io=0;
for(int i=0;i<alln-1;i++){
int b=*(yu+i);
if(b==g){
*(s->jk+io)=build(i+2);
io++;
}
}
}
return s;
}
int sdf(node* s,int x){
if(s->h==0&&s->num==x){
return 1;
}
if(s->h==0&&s->num!=x){
int qwe=0;
for(int i=0;i<s->body;i++){
node** p=s->jk;
if(sdf(*(p+i),x)==1){
qwe=1;
break;
}
}
return qwe;
}
if(s->h==1){
return 0;
}
}
void show(int x){
node* cp=pp;
while(true){
select(cp);
cout<<n<<" ";
int ui=sdf(now,x);
if(ui==1){cp=now;changeall=0;change(cp);n=-1;minw=-1;}
else{action(now);n=-1;minw=-1;}
number(cp);
if(cv==1){cv=0;cout<<endl;break;}
cv=0;
}
}
void change(node* s){
if(s->h==0){
changeall=changeall+s->food;
for(int i=0;i<s->body;i++){
node** p=s->jk;
change(*(p+i));
}
}
}
void action(node* s){
if(s->h==0){
s->h=1;
changeall=changeall-s->food;
for(int i=0;i<s->body;i++){
node** p=s->jk;
action(*(p+i));
}
}
}
void number(node* s){
if(s->h==0){cv++;
for(int i=0;i<s->body;i++){
node** p=s->jk;
node* cer=*(p+i);
if(cer->h==0){
cv++;break;
}
}
}
}
long long getw(node* s){
if(s->h==0){
long long allnow=s->food;
if(s->body==0){
long long cvbn=changeall-allnow-allnow;
if(cvbn>=0){
s->w=cvbn;
}
else{
s->w=cvbn*-1;
}
return allnow;
}
for(int i=0;i<s->body;i++){
node** p=s->jk;
allnow=allnow+getw(*(p+i));
}
long long cvbn=changeall-allnow-allnow;
if(cvbn>=0){
s->w=cvbn;
}
else{
s->w=cvbn*-1;
}
return allnow;
}
else{return 0;}
}
void select(node* s){
getw(s);
selectnow(s);
}
void selectnow(node* s){
if(s->h==0){
if(minw==-1&&n==-1){
n=s->num;
minw=s->w;
now=s;
}
else{
if(s->w==minw&&s->num<n){
n=s->num;
minw=s->w;
now=s;
}
if(s->w<minw){
n=s->num;
minw=s->w;
now=s;
}
}
for(int i=0;i<s->body;i++){
node** p=s->jk;
selectnow(*(p+i));
}
}
}
};
int main(){
int n,m;
cin>>n>>m;
long long* p=new long long[n];
int* cc=new int[n-1];
int* df=new int[m];
for(int i=0;i<n;i++){
long long b;
cin>>b;
*(p+i)=b;
}
for(int i=0;i<n-1;i++){
int b;
cin>>b;
*(cc+i)=b;
}
for(int i=0;i<m;i++){
int b;
cin>>b;
*(df+i)=b;
}
tree* tr=new tree;
tr->createtree(n,p,cc);
for(int i=0;i<m;i++){
tr->show(*(df+i));
tr->ert();
}
delete[] p;
delete[] cc;
delete[] df;
delete tr;
return 0;
}
没想到最终还是自己搞出来的,唉,记录一下,警告自己,下次一定要注意!!!