• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            poj 3764 The xor-longest Path 字典樹 + Xor

               這題意思很簡單。求一棵樹里面的一條路徑,使得其異或權(就是將路徑里面所有邊的權值異
            或起來)最大。
               這個題有兩步。第一步是假定根為節點0,求出根到其它節點的異或距離,保存在數組xor里面,
            這個dfs一下即可。然后,用xor[i]^xor[j]就能代表節點i到節點j的路徑。這個結論可以這么看。
            如果,i和j之間的路徑經過根節點,那么上面的結論肯定是正確的。如果,該路徑不經過根,那么
            xor[i]和xor[j]必定保護從根到某個節點的相同的一段子路徑,根據異或的性質,這段子路徑會
            被消掉,所以這個結論也是這確的。。。
               第二步就是枚舉,xor[i]^xor[j]使得結果最大了。如果直接暴力,平方的算法肯定會超時的。
            由于每個值可以表示成2進制,如果把其它xor值都保存在字典樹里面,用當前的xor[i]去字典樹
            里面,一遍就可以找到異或最大值。
               另外,由于樹的點數太多,只能用鄰接表,用vector模擬鄰接表果斷超時了。。。
            改成靜態鏈表才過。。。

               代碼如下:
            #include <stdio.h>
            #include <string.h>
            #include <algorithm>
            #include <vector>
            using namespace std;

            const int MAX = 100010;
            int nXor[MAX];
            bool bVis[MAX];
            int nFirst[MAX];
            struct Edge
            {
                int nE;
                int nW;
                int nNext;
            };
            Edge egs[MAX * 2];

            struct Node
            {
                Node* pSons[2];
            };
            Node nodes[MAX * 32];
            Node* pRoot = &nodes[0];
            int nNew;

            void GetBCode(int nL, int* nBCode, int& nLen)
            {
                nLen = 0;
                while (nLen <= 30)
                {
                    nBCode[nLen++] = nL % 2;
                    nL >>= 1;
                }
                reverse(nBCode, nBCode + nLen);
            }

            void Insert(int nL)
            {
                int nLen = 0;
                int i = 0;
                int nBCode[32];

                GetBCode(nL, nBCode, nLen);
                Node* pNode = pRoot;

                while (i < nLen)
                {
                    if (pNode->pSons[nBCode[i]])
                    {
                        pNode = pNode->pSons[nBCode[i]];
                    }
                    else
                    {
                        memset(nodes + nNew, 0, sizeof(nodes[nNew]));
                        pNode->pSons[nBCode[i]] = nodes + nNew;
                        pNode = nodes + nNew;
                        ++nNew;
                    }
                    ++i;
                }
            }

            int FindMax(int nL)
            {
                int nLen = 0;
                int nAns = 0;
                int i = 0;
                int nBCode[32];
                Node* pNode = pRoot;
                
                GetBCode(nL, nBCode, nLen);
                while (i < nLen)
                {
                    int nBest = (nBCode[i] == 0 ? 1 : 0);
                    int nBad = (nBCode[i] == 0 ? 0 : 1);
                    if (pNode->pSons[nBest])
                    {
                        nAns = 2 * nAns + nBest;
                        pNode = pNode->pSons[nBest];
                    }
                    else if (pNode->pSons[nBad])
                    {
                        nAns = 2 * nAns + nBad;
                        pNode = pNode->pSons[nBad];
                    }
                    else break;
                    ++i;
                }

                return nAns ^ nL;
            }

            void Dfs(int nV, int nL)
            {
                nXor[nV] = nL;
                bVis[nV] = true;
                for (int e = nFirst[nV]; e != -1; e = egs[e].nNext)
                {
                    if (!bVis[egs[e].nE])
                    {
                        Dfs(egs[e].nE, nL ^ egs[e].nW);
                    }
                }
            }

            int main()
            {
                int nN;
                int nU, nV, nW;
                
                while (scanf("%d", &nN) == 1)
                {
                    for (int i = 0; i < nN; ++i) nFirst[i] = -1;
                    for (int i = 1, j = 0; i < nN; ++i)
                    {
                        scanf("%d%d%d", &nU, &nV, &nW);
                        egs[j].nE = nV;
                        egs[j].nW = nW;
                        egs[j].nNext = nFirst[nU];
                        nFirst[nU] = j++;
                        egs[j].nE = nU;
                        egs[j].nW = nW;
                        egs[j].nNext = nFirst[nV];
                        nFirst[nV] = j++;
                    }

                    memset(bVis, falsesizeof(bool) * nN);
                    Dfs(0, 0);

                    memset(&nodes[0], 0, sizeof(Node));
                    nNew = 1;
                    int nAns = 0;
                    
                    for (int i = 0; i < nN; ++i)
                    {
                        nAns = max(nAns, FindMax(nXor[i]));
                        Insert(nXor[i]);
                    }
                    printf("%d\n", nAns);
                }

                return 0;
            }

            posted on 2012-10-12 20:12 yx 閱讀(1023) 評論(0)  編輯 收藏 引用 所屬分類: 數據結構

            <2012年10月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導航

            統計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學

            網友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            精品无码久久久久国产动漫3d| 国产精品久久久久久久久鸭| 久久久免费精品re6| 日本强好片久久久久久AAA | 久久成人影院精品777| 久久婷婷午色综合夜啪| 国产成人综合久久久久久| 精品综合久久久久久97超人| 久久久久久久人妻无码中文字幕爆 | 国产午夜精品理论片久久| 99久久久国产精品免费无卡顿 | 77777亚洲午夜久久多喷| 久久精品无码午夜福利理论片| 亚洲va久久久噜噜噜久久狠狠 | 亚洲中文字幕无码一久久区| 亚洲乱码中文字幕久久孕妇黑人| 久久人妻无码中文字幕| 人妻精品久久久久中文字幕69| 青青草原精品99久久精品66| 久久777国产线看观看精品| 91精品国产91久久久久久青草| 国产成人久久777777| 三级韩国一区久久二区综合| 狠狠色丁香婷婷久久综合五月| 色欲综合久久中文字幕网| 久久精品国产99国产电影网| 久久综合五月丁香久久激情| 一级做a爰片久久毛片毛片| 久久久精品人妻一区二区三区四| 亚洲精品国产成人99久久| 热综合一本伊人久久精品| 久久久久亚洲av无码专区喷水 | 香蕉aa三级久久毛片 | 日本加勒比久久精品| 无码国内精品久久人妻麻豆按摩| 亚洲va久久久久| 久久综合狠狠色综合伊人| 亚洲精品成人久久久| 久久不射电影网| 久久国产热精品波多野结衣AV| 久久亚洲AV永久无码精品|