主要問題: 樹如何編號(重點:如何體現父子關係)
樹的編號方式:
1)讀入給了編號並給予父子關係 (父子關係已給出) 處理:同存圖
2)將數組轉化爲一個樹 父子關係體現在其編號上(編號的關係->父子關係)典型:線段樹,堆(lson:2*x rson: 2*x+1)
void dfs(int x)
{
cin>>a[x].x>>a[x].w;
a[x].x*=2;
if(a[x].w==0)
{
dfs(x*2);dfs(x*2+1);
}
}
3)直接搞dfs序,一邊深搜一邊編號
void find()
{
cnt++;int x=cnt;
int a,b;cin>>a>>b;
if(b==0)
{
int l=cnt+1,r;find();
r=cnt+1;find();
v[x].push_back(l);v[x].push_back(r);
}
}
Then是完整代碼
方法1:dfs序
由於輸入的訪問次序與dfs序相同,所以直接做一遍dfs找出lson,rson即可,無需額外存儲父子關係
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=1005;
vector<int> v[maxn];
int f[maxn][maxn];
int cnt=0;
int n;
void find()
{
cnt++;int x=cnt;
int w,val;cin>>w>>val;
w*=2;
if(val==0)
{
int l=cnt+1,r;find();
r=cnt+1;find();
for(int tim=w;tim<=n;tim++)
{
for(int p=0;p<=tim-w;p++)
{
int temp=f[l][p]+f[r][tim-w-p];
f[x][tim]=max(f[x][tim],temp);
}
}
}
else
{
for(int tim=w;tim<=n;tim++)
{
f[cnt][tim]=min(val,(tim-w)/5);
}
}
}
int main()
{
cin>>n;n--;
find();
cout<<f[1][n]<<endl;
return 0;
}
方法2:採用線段樹的存儲方法(lson=2*x,rson=2*x+1)
此方法可能存在空結點,沒有完全利用。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn=1005;
struct node
{
int x;int w;
}a[maxn];
int f[maxn][maxn];
int cnt;node k;
void dfs(int x)
{
cin>>a[x].x>>a[x].w;
a[x].x*=2;
if(a[x].w==0)
{
dfs(x*2);dfs(x*2+1);
}
}
int find(int x,int cost)
{
if(cost==0||f[x][cost]) return f[x][cost];
if(a[x].w) return f[x][cost]=min(a[x].w,(cost-a[x].x)/5);
for(int p=0;p<=cost-a[x].x;p++)
{
int temp=find(x*2,p)+find(x*2+1,cost-p-a[x].x);
f[x][cost]=max(f[x][cost],temp);
}
return f[x][cost];
}
int main()
{
int t;scanf("%d",&t);t-=1;
dfs(1);
cnt=0;
cout<<find(1,t)<<endl;
return 0;
}