Poj 3013 big Christmas tree (the Shortest Path Dijkstra + priority queue optimization, spfa)
ACM
Address: poj 3013
Question:
The Christmas tree consists of N nodes and e edges. The node number is 1-N and the root is 1. Select some edges so that all nodes form a tree, the cost of edge selection is (the weight of the Child vertex) × (the value of this edge ). The minimum price.
Analysis:
Simply looking at the cost calculated by each vertex, it is obviously the value of the edge from the root to the node. Therefore, this is a simple single-source short circuit problem.
However, there are still many pitfalls.
The number of vertices is as high as. The number of vertices cannot be saved using matrices, but only edges can be used.
In addition, the path and result will exceed the int value, so we need to increase the INF upper limit,(1<<16)*50000
You can.
You can use Dijkstra + priority queue or spfa. It seems that spfa will be faster. I use Dijkstra here. It takes more than 1 s... I will use spfa again later.
I used spfa to do it again and found that it was more than 1 s. I saw STL used more =.
Well, leave a template.
Code:
(Dijkstra + priority_queue)
/** Author: illuz <iilluzen[at]gmail.com>* File: 3013.cpp* Create Date: 2014-07-27 09:54:35* Descripton: dijkstra */#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#include <vector>#include <queue>#define repf(i,a,b) for(int i=(a);i<=(b);i++)const int N = 50100;const long long INF = (long long)(1<<16)*N;struct Edge {int from, to;int dist;};struct HeapNode {int d;int u;bool operator < (const HeapNode rhs) const {return d > rhs.d;}};struct Dijkstra {int n, m;// number of nodes and edgesvector<Edge> edges;vector<int> G[N];// graphbool vis[N];// visited?long long d[N];// disint p[N];// prevent edgevoid init(int _n) {n = _n;}void relief() {for (int i = 0; i < n; i++) {G[i].clear();}edges.clear();}void AddEdge(int from, int to, int dist) {// if non-directed, add twiceedges.push_back((Edge){from, to, dist});m = edges.size();G[from].push_back(m - 1);}void dijkstra(int s) {priority_queue<HeapNode> Q;for (int i = 0; i < n; i++) {d[i] = INF;vis[i] = 0;}d[s] = 0;Q.push((HeapNode){0, s});while (!Q.empty()) {HeapNode x = Q.top();Q.pop();int u = x.u;if (vis[u]) {continue;}vis[u] = true;for (int i = 0; i < G[u].size(); i++) {// update the u's linking nodesEdge& e = edges[G[u][i]];//ref for convenientif (d[e.to] > d[u] + e.dist) {d[e.to] = d[u] + e.dist;p[e.to] = G[u][i];Q.push((HeapNode){d[e.to], e.to});}}}}};int t;int e, v, x, y, d, w[N];int main() {scanf("%d", &t);Dijkstra di;while (t--) {scanf("%d%d", &v, &e);di.init(v);repf (i, 0, v - 1) {scanf("%d" ,&w[i]);}repf (i, 0, e - 1) {scanf("%d%d%d", &x, &y, &d);di.AddEdge(x - 1, y - 1, d);di.AddEdge(y - 1, x - 1, d);}di.dijkstra(0);long long ans = 0;bool ring = false;repf (i, 0, v - 1) {if (di.d[i] == INF) {ring = true;}ans += w[i] * di.d[i];}if (ring) {cout << "No Answer" << endl;} else {cout << ans << endl;}if (t)// if not the last casedi.relief();}return 0;}
(Spfa)
/** Author: illuz <iilluzen[at]gmail.com>* File: 3013_spfa.cpp* Create Date: 2014-07-27 15:44:45* Descripton: spfa */#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#include <vector>#include <queue>#define repf(i,a,b) for(int i=(a);i<=(b);i++)const int N = 50100;const long long INF = (long long)(1<<16)*N;struct Edge {int from, to;int spst;};struct SPFA {int n, m;vector<Edge> edges;vector<int> G[N];// the edges which from ibool vis[N];long long d[N];// spsint p[N];// preventvoid init(int _n) {n = _n;}void relief() {for (int i = 0; i < n; i++)G[i].clear();edges.clear();}void AddEdge(int from, int to, int spst) {// if non-sprected, add twiceedges.push_back((Edge){from, to, spst});m = edges.size();G[from].push_back(m - 1);}void spfa(int s) {queue<int> Q;while (!Q.empty())Q.pop();for (int i = 0; i < n; i++) {d[i] = INF;vis[i] = 0;}d[s] = 0;vis[s] = 1;Q.push(s);while (!Q.empty()) {int u = Q.front();Q.pop();vis[u] = 0;for (int i = 0; i < G[u].size(); i++) {Edge& e = edges[G[u][i]];if (d[e.to] > d[u] + e.spst) {d[e.to] = d[u] + e.spst;p[e.to] = G[u][i];if (!vis[e.to]) {vis[e.to] = 1;Q.push(e.to);}}}}}};int t;int e, v, x, y, d, w[N];int main() {scanf("%d", &t);SPFA sp;while (t--) {scanf("%d%d", &v, &e);sp.init(v);repf (i, 0, v - 1) {scanf("%d" ,&w[i]);}repf (i, 0, e - 1) {scanf("%d%d%d", &x, &y, &d);sp.AddEdge(x - 1, y - 1, d);sp.AddEdge(y - 1, x - 1, d);}sp.spfa(0);long long ans = 0;bool ring = false;repf (i, 0, v - 1) {if (sp.d[i] == INF) {ring = true;}ans += w[i] * sp.d[i];}if (ring) {cout << "No Answer" << endl;} else {cout << ans << endl;}if (t)// if not the last casesp.relief();}return 0;}