哈夫曼樹 HDU 1053 HDU 2527

來源:互聯網
上載者:User
#include<iostream> / * HDU 2527 裸的哈夫曼樹 * /#include<string>#include<map>using namespace std;#define manx 100#define inf 9999999;map<char,int>mp;struct node{    int weight;    int parent;    int lch;    int rch;    string code;  ///  哈夫曼碼值     string val;  ///  字元 };void init(node *hfnode,int n){ /// 初始化     for(int i=0;i<(n<<1)-1;i++){        hfnode[i].weight=0;        hfnode[i].parent=-1;        hfnode[i].lch = hfnode[i].rch = -1;        hfnode[i].code.clear();        hfnode[i].val.clear();    }}void make_tree(node *hfnode,int n){  /// 建哈夫曼樹     int m1, m2, x1, x2;    for(int i=1;i<n;i++){        m1 = m2 = inf;  ///  記錄最小和其次小的值         x1 = x2 = 0;  ///   記錄最小和其次的值的位置         for(int j=1;j<n+i;j++){    ///   查詢,找到最小和其次小的位置             if(hfnode[j].weight < m1 && hfnode[j].parent < 0){                m2 = m1;                x2 = x1;                m1 = hfnode[j].weight;                x1 = j;            }            else if(hfnode[j].weight < m2 && hfnode[j].parent <0 ){                m2 = hfnode[j].weight;                x2 = j;            }        }        hfnode[x1].parent = n+i;  ///  然後父親節點進行更新         hfnode[x2].parent = n+i;        hfnode[n+i].weight = hfnode[x1].weight + hfnode[x2].weight;  ///  權值更新         hfnode[n+i].lch = x1;   ///  左右孩子進行記錄         hfnode[n+i].rch = x2;    }}void tree_code(node *hfnode, int m, int n ){  ///  採用遞迴的形式建立哈夫曼編碼值     if( m<=n ) return ;    if(hfnode[m].lch > 0) {        hfnode[ hfnode[m].lch ].code = "0";    }    if(hfnode[m].rch > 0) {        hfnode[ hfnode[m].rch ].code = "1";    }    tree_code( hfnode, hfnode[m].lch, n );     tree_code( hfnode, hfnode[m].rch, n ); }string e,hh;  /// hh 表示哈夫曼編碼,它的長度也表示深度               /// e 表示目標 值 void tree_dfs( node *hfnode,int m,int n,string s,int &flag ){  /// 深搜     if( hfnode[m].val == e ){  /// 查詢         flag=1, hh=s;          return ;    }    if(flag || m <= n) return ;    if(hfnode[m].lch > 0) {        tree_dfs(hfnode,hfnode[m].lch, n, s+hfnode[ hfnode[m].lch ].code, flag);    }    if(hfnode[m].rch > 0) {        tree_dfs(hfnode,hfnode[m].rch, n, s+hfnode[ hfnode[m].rch ].code, flag);    }}int main(){    node hfnode[manx*4];    string str;    int n1,t;    cin>>t;    while(t--){         int ans1;        cin>>ans1>>str;        mp.clear();        n1 = str.size();        init(hfnode,manx);        int n=0,ans=1;        for(int i=0;i<n1;i++) mp[str[i]]++;        for(int i=0;i<n1;i++){            if(mp[str[i]]){                hfnode[++n].weight = mp[str[i]];                hfnode[n].val = str[i];                mp[str[i]]=0;             }        }        int flag=0,sum=0,du=0;        if(n==1) {             sum = hfnode[1].weight;            if(sum<=ans1) printf("yes\n");            else printf("no\n");            continue;        }        make_tree(hfnode,n);         tree_code( hfnode,(n<<1)-1 ,n );         string hfcode;                for(int i=1;i<=n;i++){            flag = 0;            hfcode.clear();            e.clear();            hh.clear();            e = hfnode[i].val;            tree_dfs( hfnode, (n<<1)-1, n, hfcode, flag );            sum += (hh.size())*(hfnode[i].weight);        }         if(sum<=ans1) printf("yes\n");        else printf("no\n");    }}

其實挺簡單的,前幾天自己寫的課設就是哈夫曼樹..

題意:要你求 8*str.size()   , sum(最優權值),   8*str.size()  /  (sum*1.0) 

代碼:

/*因為總計就是27個字元(狀態),所以深搜是完全沒有壓力的 */ #include<iostream>#include<string>#include<map>using namespace std;#define manx 100#define inf 9999999;map<char,int>mp;struct node{    int weight;    int parent;    int lch;    int rch;    string code;  ///  哈夫曼碼值     string val;  ///  字元 };void init(node *hfnode,int n){ /// 初始化     for(int i=0;i<(n<<1)-1;i++){        hfnode[i].weight=0;        hfnode[i].parent=-1;        hfnode[i].lch = hfnode[i].rch = -1;        hfnode[i].code.clear();        hfnode[i].val.clear();    }}void make_tree(node *hfnode,int n){  /// 建哈夫曼樹     int m1, m2, x1, x2;    for(int i=1;i<n;i++){        m1 = m2 = inf;  ///  記錄最小和其次小的值         x1 = x2 = 0;  ///   記錄最小和其次的值的位置         for(int j=1;j<n+i;j++){    ///   查詢,找到最小和其次小的位置             if(hfnode[j].weight < m1 && hfnode[j].parent < 0){                m2 = m1;                x2 = x1;                m1 = hfnode[j].weight;                x1 = j;            }            else if(hfnode[j].weight < m2 && hfnode[j].parent <0 ){                m2 = hfnode[j].weight;                x2 = j;            }        }        hfnode[x1].parent = n+i;  ///  然後父親節點進行更新         hfnode[x2].parent = n+i;        hfnode[n+i].weight = hfnode[x1].weight + hfnode[x2].weight;  ///  權值更新         hfnode[n+i].lch = x1;   ///  左右孩子進行記錄         hfnode[n+i].rch = x2;    }}void tree_code(node *hfnode, int m, int n ){  ///  採用遞迴的形式建立哈夫曼編碼值     if( m<=n ) return ;    if(hfnode[m].lch > 0) {        hfnode[ hfnode[m].lch ].code = "0";    }    if(hfnode[m].rch > 0) {        hfnode[ hfnode[m].rch ].code = "1";    }    tree_code( hfnode, hfnode[m].lch, n );      tree_code( hfnode, hfnode[m].rch, n ); }string e,hh; ///  hh表示哈夫曼編碼,它的長度也算是深度             ///  e 表示目標值 void tree_dfs( node *hfnode,int m,int n,string s,int &flag ){  /// 深搜     if( hfnode[m].val == e ){  /// 當查詢到時         flag=1, hh=s;        return ;    }    if(flag || m <= n) return ; ///  兩個成立的條件     if(hfnode[m].lch > 0) {        tree_dfs(hfnode,hfnode[m].lch, n, s+hfnode[ hfnode[m].lch ].code, flag);    }    if(hfnode[m].rch > 0) {        tree_dfs(hfnode,hfnode[m].rch, n, s+hfnode[ hfnode[m].rch ].code, flag);    }}int main(){    node hfnode[manx*4];    string str;    int n1;     while(getline(cin,str)){        mp.clear();        if(str=="END") break;        n1 = str.size();        init(hfnode,manx);        int n=0,ans=1;        for(int i=0;i<n1;i++) mp[str[i]]++;  /// map 統計單個字元出現的次數         for(int i=0;i<n1;i++){            if(mp[str[i]]){                hfnode[++n].weight = mp[str[i]];                hfnode[n].val = str[i];                mp[str[i]]=0;             }        }        if(n==1) { ////  要注意             cout<<8*str.size()<<" "<<hfnode[n].weight<<" ";            printf("%.1lf\n",(8*str.size())/(hfnode[n].weight*1.0));            continue;        }        make_tree(hfnode,n);         tree_code( hfnode,(n<<1)-1 ,n );         string hfcode;        int flag=0,sum=0,du=0;        for(int i=1;i<=n;i++){            flag = 0;            hfcode.clear();            e = hfnode[i].val;            tree_dfs( hfnode, (n<<1)-1, n, hfcode, flag );            sum += (hh.size())*(hfnode[i].weight);        }         cout<<8*str.size()<<" "<<sum<<" ";        printf("%.1lf\n",(8*str.size())/(sum*1.0));    }}/*THE_CAT_IN_THE_HATAAAAABCD*/

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.