1. 程式人生 > >POJ ~ 3013 ~ Big Christmas Tree (最短路徑樹,思維)

POJ ~ 3013 ~ Big Christmas Tree (最短路徑樹,思維)

在這裡插入圖片描述

題意

T組測試資料,每組先輸入n,m表示有一個n個點m條邊的無向圖,然後輸入n個點的點權,然後輸入m條邊(u,v,w),求一棵以1為根節點的數使得該樹花費最小,輸出最小花費,如果無法構建成一棵樹輸出“No Answer”。
樹的花費為:\sum(邊權*子樹的點權和)

思路

通過推樣例可以發現每個點的點權需要乘以這個點到根結點的所有邊的邊權,所以可以得到
\sum邊權*子樹的點權和 = \sum該點根節點的路徑*點權
所以直接跑一遍最短路統計答案即可。
注意開long long。

//#include<bits/stdc++.h>
#include <iostream>
#include <cstdio> #include <cstring> #include <queue> using namespace std; const int MAXN = 1e5+5; typedef long long LL; const LL INF = 0x3f3f3f3f3f3f3f3f; struct Edge { int from, to; LL dist; //起點,終點,距離 Edge(int from, int to, LL dist):from(from), to(to), dist(dist) {}
}; struct Dijkstra { int n, m; //結點數,邊數(包括反向弧) vector<Edge> edges; //邊表。edges[e]和edges[e^1]互為反向弧 vector<int> G[MAXN]; //鄰接表,G[i][j]表示結點i的第j條邊在edges陣列中的序號 int vis[MAXN]; //標記陣列 LL d[MAXN]; //s到各個點的最短路 int p[MAXN]; //上一條弧
void init(int n) { this->n = n; edges.clear(); for (int i = 0; i <= n; i++) G[i].clear(); } void AddEdge(int from, int to, int dist) { edges.push_back(Edge(from, to, dist)); m = edges.size(); G[from].push_back(m - 1); } struct HeapNode { int from; LL dist; bool operator < (const HeapNode& rhs) const { return rhs.dist < dist; } HeapNode(int u, LL w): from(u), dist(w) {} }; void dijkstra(int s) { priority_queue<HeapNode> Q; for (int i = 0; i <= n; i++) d[i] = INF; memset(vis, 0, sizeof(vis)); d[s] = 0; Q.push(HeapNode(s, 0)); while (!Q.empty()) { HeapNode x = Q.top(); Q.pop(); int u = x.from; if (vis[u]) continue; vis[u] = true; for (int i = 0; i < G[u].size(); i++) { Edge& e = edges[G[u][i]]; if (d[e.to] > d[u] + e.dist) { d[e.to] = d[u] + e.dist; p[e.to] = G[u][i]; Q.push(HeapNode(e.to, d[e.to])); } } } } }gao; int a[MAXN]; int main() { int T; scanf("%d", &T); while (T--) { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); gao.init(n); while (m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); gao.AddEdge(u, v, w); gao.AddEdge(v, u, w); } gao.dijkstra(1); LL ans = 0; for (int i = 1; i <= n; i++) { if (gao.d[i] == INF) { ans = -1; break; } ans += a[i]*gao.d[i]; } if (ans != -1) printf("%lld\n", ans); else printf("No Answer\n"); } return 0; } /* 2 2 1 1 1 1 2 15 7 7 200 10 20 30 40 50 60 1 2 1 2 3 3 2 4 2 3 5 4 3 7 2 3 6 3 1 5 9 */

相關推薦

POJ ~ 3013 ~ Big Christmas Tree 路徑思維

題意 T組測試資料,每組先輸入n,m表示有一個n個點m條邊的無向圖,然後輸入n個點的點權,然後輸入m條邊(u,v,w),求一棵以1為根節點的數使得該樹花費最小,輸出最小花費,如果無法構建成一棵樹輸出“No Answer”。 樹的花費為:∑\sum∑(邊權*子樹

一個人的旅行 路徑設虛擬節點

雖然草兒是個路痴(就是在杭電待了一年多,居然還會在校園裡迷路的人,汗~),但是草兒仍然很喜歡旅行,因為在旅途中 會遇見很多人(白馬王子,^0^),很多事,還能豐富自己的閱歷,還可以看美麗的風景……草兒想去很多地方,她想要去東京鐵塔看夜景,去威尼斯看電影,去陽明山上看海芋,去紐約純粹看雪景,去巴黎喝咖

HDU 2544路徑 SPFA 演算法模板

F - 最短路 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit

資料結構——帶權有向圖路徑演算法Dijkstra演算法

Dijkstra演算法是由荷蘭電腦科學家艾茲格·迪科斯徹發現的。演算法解決的是有向圖中最短路徑問題。 舉例來說,如果圖中的頂點表示城市,而邊上的權重表示著城市間開車行經的距離。 Dijkstra演算法可以用來找到兩個城市之間的最短路徑。 Dijkstra演算法的輸入包含了一個有權重的有向圖G,以及G中的一個

六度分離路徑之Floyd演算法

六度分離點我找原題Time Limit : 5000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)Total Submission(s) : 31   Accepted Submission(s) : 14Font: Times

POJ2594Treasure Exploration路徑覆蓋相交

級別 lang output stream lines cati ast urn 題意 Treasure Exploration Have you ever read any book about treasure exploration? Have you ever

POJ ~ 1904 ~ King's Quest 強連通 + 縮點思維

題意 先輸入N表示有n個王子,接下來N行,每行先輸入K表示,第i個王子有K個喜歡的公主,然後輸入這K個公主的編號。每個王子只能和喜歡的妹子結婚,大臣給出一個匹配表,每個王子都和一個妹子結婚,但是國王不滿

POJ - 2387】Til the Cows Come Home路徑 Dijkstra演算法

Til the Cows Come Home 大奶牛很熱愛加班,他和朋友在凌晨一點吃完海底撈後又一個人回公司加班,為了多加班他希望可以找最短的距離回到公司。深圳市裡有N個(2 <= N <= 1000)個公交站,編號分別為1..N。深圳是大城市,公交車整天跑跑跑。公交站1是大奶牛的位置,公司所在

hdu 2544路徑

cst cstring while span code 最短路徑 bre sha nbsp 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #inclu

【HDOJ】1874-暢通工程續路徑dijkstra

amp include using get dijk 找到 間距 距離 ace 1874-暢通工程續 http://acm.hdu.edu.cn/showproblem.php?pid=1874 題意:略。 思路:最短路dijkstra模板,不過要先要把題裏輸入的把兩點間距

uva658路徑+隱式圖+狀態壓縮

匹配 define top har 讀者 還記得 題意 priority 節點 題目連接(vj):https://vjudge.net/problem/UVA-658 題意:補丁在修正 bug 時,有時也會引入新的 bug。假定有 n(n≤20)個潛在 bug 和 m(m≤

HDU - 4871 Shortest-path tree (路徑+ 分治)

get -- epp return 深度 分析 std inf += 題意:給你一張帶權無向圖,先求出這張圖從點1出發的最短路樹,再求在樹上經過k個節點最長的路徑值,以及個數. 分析:首先求最短路樹,跑一遍最短路之後dfs一遍即可建出最短路樹. 第二個問題,樹分治解決. 對

洛谷P3953 逛公園NOIP2017/長路拓撲排序動態規劃

洛谷題目傳送門 又是一年聯賽季。NOIP2017至此收官了。 這個其實是比較套路的圖論DP了,但是細節有點噁心。 先求出\(1\)到所有點的最短路\(d1\),和所有點到\(n\)的最短路\(dn\)。 設\(f_{i,j}\)表示\(i\)號點,所有與\(d1\)差距不超過\(j\)的路徑條數。轉移

【loj】#10064. 「一本通 3.1 例 1」黑暗城堡路徑生成樹 dijkstra+Prim

題目描述: 你知道黑暗城堡有 N個房間,M 條可以製造的雙向通道,以及每條通道的長度。 城堡是樹形的並且滿足下面的條件: 設 Di​ 為如果所有的通道都被修建,第 i 號房間與第 1 號房間的最短路徑長度; 而 Si​ 為實際修建的樹形城堡中第 i 號房間與第 1 號房間的路徑長度;

【CCF 201609-4】交通規劃小的路徑 Dijkstra

題目抽象 要求所有結點與源結點連通,使得所有邊權之和最小。即求最小的最短路徑樹。 大致思路 演算法:通過Dijkstra演算法可以構建最短路徑樹,如何保證這棵樹最小呢?這就需要一些變形了: 每個結點需要記錄它的前驅邊,每次鬆弛的條件是u.d + e ≤ v.d,

1030 Travel Plan 30 分路徑 and dfs

#include<bits/stdc++.h> using namespace std; const int N=510; const int inf=0x3f3f3f3f; int mp[N][N]; bool vis[N]; int dis[N]; int n,m,s,D; int

1072 Gas Station 30 分路徑

  #include<bits/stdc++.h> using namespace std; const int N=1e3+100; int n,m,k,Ds; int mp[N][N]; int dis[N]; int vis[N]; int inf=0x3f3f3f3

2018.12.08【FJOI2014】【BZOJ4016】【洛谷P2993】路徑問題短路點分治

BZOJ傳送門 洛谷傳送門 解析: 辛辛苦苦調了半天發現是最短路樹建錯了。。。 思路: 首先跑一個最短路,然後將每個點的所有出邊按照出點編號排序,DFS建出最短路樹。 這樣建樹才能夠保證字典序是最小的。(naive的我按照前驅結點建樹WA哭了) 那麼看一

PAT--Emergency路徑的應用題目講解

1003 Emergency (25 分) As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several

用棧 求迷宮問題路徑和全部路徑

這是資料結構的作業,便找書邊看網上,然後自己慢慢寫出來的,這裡面主要是回溯法。 因為課本上是打印出一條路徑,然後我在想怎樣能將所有的路徑都輸出來,方法:就是當求出一條路徑後,將出口點變成可以走的點(因為之前將其值變成了-1),並且將棧頂元素出棧,還需要得到現在棧頂元素的i,j