解题思路
参考哈夫曼树,这道题要加上一个储存字母的域。
带权路径长短:
所以我们在中序遍历时,对于每一个叶子,去记录它的深度就好了
PS:注意这道题要按子母序输出。(先保存下来,最后按顺序输出)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#define ll long long
using namespace std;
map<char,string>mp;
char w[300];
int n,ans;
struct c{
char c;
int x,ls,rs,p;
}a[300],f[300];
bool cmp(c l,c r)
{
if(l.x==r.x)return l.p<r.p;
return l.x<r.x;
}
void out(int t,string s,int dep){
if(f[t].x==0)return;
out(f[t].ls,s+'0',dep+1);
if(f[t].ls==0&&f[t].rs==0)
{
mp[f[t].c]=s;
ans=ans+dep*f[t].x;
}
out(f[t].rs,s+'1',dep+1);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>a[i].c;
w[i]=a[i].c;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].x);
a[i].p=i;
f[i].x=a[i].x;
f[i].c=a[i].c;
}
int i=n,t=n;
while(i>1)
{
sort(a+1,a+i+1,cmp);
f[++t].x=a[1].x+a[2].x;
f[t].ls=a[1].p,f[t].rs=a[2].p;
a[1].x=f[t].x,a[1].p=t,a[1].c=char('z'+t);
a[2].x=a[i].x,a[2].p=a[i].p,a[2].c=a[i].c;
i--;
}
out(t,"",0);
sort(w+1,w+n+1);
for(int i=1;i<=n;i++)
cout<<w[i]<<":"<<mp[w[i]]<<endl;
printf("%d",ans);
}
/*7
a b c d e f g
3 7 8 2 5 8 4*/