题意:
给定一棵树,树的点编号为1到n,以1为根,树的边有边权,定义s(x,y)=x到y路径上边权的最小值。
现需要构造一个1到n的排列p[ ],使得最大,
现需要构造一个1到n的排列p[ ],使得最大,
输出这个最大值即可。
方法一:
思维
思路:突破点:s(x,y)=x到y路径上边权的最小值。
因为这是一棵树,所以x到y有且只有一条路径,路径的权值等于经过各边的权值之和,所以x到y路径上边权是固定的。又因为s(x,y)=x到y路径上边权的最小值,如果想要其最小,那么说明x和y是直接相连的(即路径上只有一条边)。
那么,我们可以构造一个排列,使得排列相邻的两点刚好就是一条边的两个端点。
所以答案便等于树的各边权值之和。
例子:
#define ll long long class Solution { public: long long work(int n, long long seed1, long long seed2, long long seed3) { vector<int> u(n);//u[i],v[i]分别表示第i条边的两个端点 vector<int> v(n); vector<int> w(n);//w[i]表示第i条边的边权 ll res=0; for(int i=1;i<n;i++){//依照题目构造树 ll seed4=((seed1+seed2)%998244353)*seed3%998244353; u[i]=i+1; v[i]=(seed4%i)+1; w[i]=seed2*seed3%12131415; seed3=seed2; seed2=seed1; seed1=seed4; } for(int i=1;i<n;i++){//各边权值相加 res+=w[i]; } return res; } };
时间复杂度:空间复杂度:
方法二:
空间优化
思路:在方法一的基础上做空间优化。
因为只需要各边的权值之和,因此只需累加边的权值。
#define ll long long class Solution { public: long long work(int n, long long seed1, long long seed2, long long seed3) { ll res=0;//各边权值之和 for(int i=1;i<n;i++){ ll seed4=((seed1+seed2)%998244353)*seed3%998244353; res+=seed2*seed3%12131415;//累加边的权值 seed3=seed2; seed2=seed1; seed1=seed4; } return res; } };
时间复杂度:
空间复杂度: