poj 3013 透過現象看本質,其實都一樣

2021-06-07 22:00:41 字數 1647 閱讀 1678

這道題目咋一看就是最小生成樹啊。

題目描述大概是這樣:

kcm要準備一顆聖誕樹,這棵樹有一些節點和邊組成。節點從1到n,根總是1.每個節點都有自己的總量,而邊的**是由邊的單價乘以子孫節點的重量。

求出這麼一顆有n個節點的樹,使花費最小。

很像最小生成樹,仔細研究,沒法這樣做。因為每條邊在找到這顆樹之前很難計算它的價值。

因為本來你算好的邊的價值,但是在去掉某些邊時,會導致邊的價值發生變化,那怎麼辦。。。。

這道題目開始我也是不知道怎麼計算,看到discuss說是最短路。試想最後已經得到乙個樹,而每條邊的價值就是子孫節點重量和乘以單價,可以轉換為,此節點重量乘以從根到本節點的最短路,這麼一轉化,問題瞬間變得簡單了。

那麼所有點的最短路徑一定是一棵樹嗎?   這個是顯然的 ,因為如果形成環了,到達某個點就出現了多個路徑,就要刪去長的那條,使其沒有環

樣例中的計算方法

4*40+3*50+2*60+3*(20+40+50+60)+2*30+1*(10+20+30+40+50+60)

=10*1+20*(1+3)+30*(2+1)+40*(4+1+3)+50*(3+1+3)+60*(1+2+3)

=10+80+90+320+350+360

=1210

題目要注意幾個地方

1、n=0或者1, 答案是0,而不是no answer

2、資料範圍大,要用long long

3、n=0或者1的時候也要將資料讀入,不能直接輸出0就不管輸入了,否則會re

4、注意是無向圖,建鄰接表的時候要雙向

5、資料量大,鄰接矩陣不行,必須鄰接表

搞清楚了這些,剩下就是簡單的spfa了

**:

#include#define maxn 50005

#define inf 10000000000000

struct edge

edge[2 * maxn];//鄰接表

int preedge[2 * maxn];//preedge[u],上一條以u為起點的邊在edge中的位置

long long dis[maxn];//最短路

bool vis[maxn];

int weight[maxn];//節點重量

int queue[20 * maxn];//鬆弛佇列

int n,m;

void init()//初始化

}void spfa()

}p = edge[p].next;//下一條以u起點的邊

} head ++;

vis[u] = false;

} bool flag = true;

long long sum = 0;

for (int i = 2; i <= n; ++ i)

sum += weight[i] * dis[i];

} if (!flag)

else

printf("%lld\n", sum);

}int main()

init();

int index = 1;

for (int i = 1; i <= m; ++ i)

if (n == 0 || n == 1)

spfa();

} return 0;

}

透過現象看本質

例子 你回家的時候,發現沒帶鑰匙,你聯絡了乙個鎖匠來開鎖,結果他很快來了,並且在一分鐘之內給你開啟了鎖,問你要1000元,你會覺得很不值 但是如果乙個鎖匠用了幾個小時或者更長時間幫你開啟了鎖,你會看到他的努力,要同樣的錢,你會覺得很合理 這實際上是乙個誤區,人往往會看到一些表面的努力,而忽略了一些隱...

外觀模式 透過現象看本質

外觀模式用於為複雜系統建立乙個簡單清晰的介面。當我們需要使用到子系統的 時,為了避免過去深入地呼叫子系統 而導致後期 難以維護,減低 和子系統的耦合性,我們需要在 和子系統中引入乙個入口。實際上就是在子系統 進行一次封裝,那麼我們在呼叫子系統 的時候就可以通過呼叫封裝的方法來呼叫,以致於後期修改子系...

大道至簡之四 透過現象看本質

大道至簡 透過現象看本質 投資總結之四 時寒冰 研究趨勢是一件充滿挑戰和趣味的事情。我深信,很多現象是有規律可循的。但是,對於趨勢的判斷尤其提前做出的判斷,短期內,很多人尤其專業研究人士是無法理解的,因為,他們在專業領域迷失太久,侷限了自己的判斷。反而是很多普通投資者根據常識甚至直覺,更能洞悉本質。...