#4#5 60pts 求助(暴力+LCA)悬1关
查看原帖
#4#5 60pts 求助(暴力+LCA)悬1关
764239
ABCgfed楼主2023/6/30 21:46

rt

#include<iostream>
using namespace std;
int root=0;
struct tree{//定义
	int value,pa,lc,rc,depth;
};
tree resident[150];
int n;
int lca(int s,int f){//最近公共祖先求两点距离
	int ans=0;
	while(1){
		if(s==f){
			return ans;
		}
		if(resident[s].depth>resident[f].depth){
			ans++;
			s=resident[s].pa;
		}
		else if(resident[s].depth<resident[f].depth){
			ans++;
			f=resident[f].pa;
		}
		else{
			ans+=2;
			s=resident[s].pa;
			f=resident[f].pa;
		}
	}
}
int dfs2(int r,int s){//遍历所有居民点到特定的医院的时间和
	int ans=0;
	ans+=lca(r,s)*resident[r].value;
	if(resident[r].lc!=-1){
		ans+=dfs2(resident[r].lc,s);
	}
	if(resident[r].rc!=-1){
		ans+=dfs2(resident[r].rc,s);
	}
	return ans;
}
int dfs1(int s){//遍历所有设置医院的可能性
	int min=99999999;
	if(dfs2(root,s)<min){
		min=dfs2(root,s);
	}
	if(resident[s].lc!=-1&&dfs2(root,resident[s].lc)<min){
		min=dfs2(root,resident[s].lc);
	}
	if(resident[s].rc!=-1&&dfs2(root,resident[s].rc)<min){
		min=dfs2(root,resident[s].rc);
	}
	return min;
}
void dealdepth(int root,int depth){//求树上每点深度
	resident[root].depth=depth;
	if(resident[root].lc!=-1){
		dealdepth(resident[root].lc,depth+1);
	}
	if(resident[root].rc!=-1){
		dealdepth(resident[root].rc,depth+1);
	}
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>resident[i].value>>resident[i].lc>>resident[i].rc;
		resident[i].lc--;
		resident[i].rc--;
		if(resident[i].lc!=0)resident[resident[i].lc].pa=i;
		if(resident[i].rc!=0)resident[resident[i].rc].pa=i;
	}
	while(1){
		if(resident[root].pa==0){
			break;
		}
		else{
			root=resident[root].pa;
		}
	}//输入
	dealdepth(root,1);
	cout<<dfs1(root);
	return 0;
}
2023/6/30 21:46
加载中...