LintCode領(lǐng)扣 題解 |Google 面試題:Fermat Point of Graphs

題目描述

有一個(gè)無(wú)向無(wú)環(huán)連通圖成肘,每條邊通過(guò)兩個(gè)頂點(diǎn)x[i],y[i]來(lái)描述帘靡,每條邊的長(zhǎng)度通過(guò)d[i]來(lái)描述淆攻。求這樣的一個(gè)點(diǎn)p行嗤,使得其他點(diǎn)到p的距離和最小已日,如果有多個(gè)這樣的點(diǎn)p,返回編號(hào)最小的昂验。

思路點(diǎn)撥

dp[i] 代表以 i 為根的子樹中的結(jié)點(diǎn)到 i 結(jié)點(diǎn)的距離和捂敌,dp[i] = sum(dp[j] + np[j] * d(i, j)),np[i] 代表以 i 為根的子樹的所有結(jié)點(diǎn)的個(gè)數(shù)既琴,np[i] = sum(np[j]) + 1占婉。

考點(diǎn)分析

該題算是比較難的一道題了,無(wú)向無(wú)環(huán)的連通圖甫恩,我們可以理解為一棵多叉樹逆济,對(duì)于一棵多叉樹要求費(fèi)馬點(diǎn),顯然需要樹形dp磺箕,不過(guò)這里我們需要dfs兩次奖慌,第一次先求出每個(gè)字?jǐn)?shù)的節(jié)點(diǎn)數(shù)np[i]和子樹中的結(jié)點(diǎn)到 i 結(jié)點(diǎn)的距離和dp[i],那么在第二個(gè)dfs中就能求出費(fèi)馬點(diǎn)的位置,具體的狀態(tài)轉(zhuǎn)移可以參考一下答案松靡。

參考程序

https://www.jiuzhang.com/solution/fermat-point-of-graphs/

/**
* 本參考程序來(lái)自九章算法简僧,由 @華助教 提供。版權(quán)所有雕欺,轉(zhuǎn)發(fā)請(qǐng)注明出處岛马。
* - 九章算法致力于幫助更多中國(guó)人找到好的工作,教師團(tuán)隊(duì)均來(lái)自硅谷和國(guó)內(nèi)的一線大公司在職工程師屠列。
* - 現(xiàn)有的面試培訓(xùn)課程包括:九章算法班啦逆,系統(tǒng)設(shè)計(jì)班,算法強(qiáng)化班笛洛,Java入門與基礎(chǔ)算法班夏志,Android 項(xiàng)目實(shí)戰(zhàn)班,
* - Big Data 項(xiàng)目實(shí)戰(zhàn)班苛让,算法面試高頻題班, 動(dòng)態(tài)規(guī)劃專題班
* - 更多詳情請(qǐng)見官方網(wǎng)站:http://www.jiuzhang.com/?source=code
*/ 

public class Solution {
    /**
     * @param x: The end points set of edges
     * @param y: The end points set of edges
     * @param d: The length of edges
     * @return: Return the index of the fermat point
     */
    class Pair {
        public int first;
        public int second;
        public Pair(int first, int second) {
            this.first = first;
            this.second = second;
        }
    } 
    long ans;
    int idx;

    void dfs1(int x, int f, List<List<Pair>> g, int[] np, long[] dp) {
        np[x] = 1;
        dp[x] = 0;
        for (int i = 0; i < g.get(x).size(); i++) {
            int y = g.get(x).get(i).first;
            if (y == f) {
                continue;
            }
            dfs1(y, x, g, np, dp);
            np[x] += np[y];
            dp[x] += dp[y] + (long)g.get(x).get(i).second * np[y];
        }
    }
    void dfs2(int x, int f, long sum, List<List<Pair>> g, int[] np, long[] dp, int n) {
        for (int i = 0; i < g.get(x).size(); i++) {
            int y = g.get(x).get(i).first;
            if (y == f) {
                continue;
            }
            long nextSum = dp[y] + (sum - dp[y] - (long)np[y] * g.get(x).get(i).second) + (long)(n - np[y]) * g.get(x).get(i).second;
            if (nextSum < ans || (nextSum == ans && x < idx)) {
                ans = nextSum;
                idx = y;
            }
            dfs2(y, x, nextSum, g, np, dp, n);
        }
    }

    public int getFermatPoint(int[] x, int[] y, int[] d) {
        // Write your code here
        int n = x.length + 1;
        List<List<Pair>> g = new ArrayList<List<Pair>>();
        for(int i = 0; i <= n; i++) {
            g.add(new ArrayList<Pair>());
        }
        for (int i = 0; i < x.length; i++) {
            g.get(x[i]).add(new Pair(y[i], d[i]));
            g.get(y[i]).add(new Pair(x[i], d[i]));
        }
        int [] np = new int[n + 1];
        long [] dp = new long[n + 1];
        dfs1(1, 0, g, np, dp);
        ans = dp[1];
        idx = 1;
        dfs2(1, 0, dp[1], g, np, dp, n);
        return idx;
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沟蔑,一起剝皮案震驚了整個(gè)濱河市湿诊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溉贿,老刑警劉巖枫吧,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異宇色,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)颁湖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門宣蠕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人甥捺,你說(shuō)我怎么就攤上這事抢蚀。” “怎么了镰禾?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵皿曲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我吴侦,道長(zhǎng)屋休,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任备韧,我火速辦了婚禮劫樟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘织堂。我一直安慰自己叠艳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布易阳。 她就那樣靜靜地躺著附较,像睡著了一般。 火紅的嫁衣襯著肌膚如雪潦俺。 梳的紋絲不亂的頭發(fā)上拒课,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音黑竞,去河邊找鬼捕发。 笑死,一個(gè)胖子當(dāng)著我的面吹牛很魂,可吹牛的內(nèi)容都是我干的扎酷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼遏匆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼法挨!你這毒婦竟也來(lái)了谁榜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凡纳,失蹤者是張志新(化名)和其女友劉穎窃植,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荐糜,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巷怜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了暴氏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片延塑。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖答渔,靈堂內(nèi)的尸體忽然破棺而出关带,到底是詐尸還是另有隱情,我是刑警寧澤沼撕,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布宋雏,位于F島的核電站,受9級(jí)特大地震影響务豺,放射性物質(zhì)發(fā)生泄漏磨总。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一冲呢、第九天 我趴在偏房一處隱蔽的房頂上張望舍败。 院中可真熱鬧,春花似錦敬拓、人聲如沸邻薯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)厕诡。三九已至,卻和暖如春营勤,著一層夾襖步出監(jiān)牢的瞬間灵嫌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工葛作, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寿羞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓赂蠢,卻偏偏與公主長(zhǎng)得像绪穆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容