You have two rows of nodes. Each row contains N nodes, numbered 0 through N-1 from the left to the right.
Within each row, adjacent nodes are already connected by edges. You are given the lengths of these edges as int[]s a and b, each containing N-1 elements. For each valid i,a[i] is the length of the edge between nodes i and (i+1) in the top row, and b[i] is the length of the edge between nodes i and (i+1) in the bottom row.
You want to add exactly K new edges to this graph. Each of the new edges must be vertical -- i.e., it must connect some vertex i in the top row to the vertex i in the bottom row. All new edges will have length 0.
By adding the K new edges we will produce a connected graph. The diameter of this graph is the maximum of all shortest distances among pairs of its nodes. In other words, the diameter is the smallest number D such that it is possible to travel from any node to any other node using a path of length D or less.
Given a, b, and the int K, compute and return the smallest possible diameter of the resulting graph.
All bridges must be vertical. This means that there are only
(The worst case) we will have 462 options in total. Let‘s try them all. We can do this with backtracking or with bit masks. Now we just need to, for each combination of bridges, calculate the diameter
In order to calculate the diameter, we need to know the maximum pairwise distance between any two distinct vertices in the graph. I recommend to use Floyd-Warshall algorithm
as its output will be a table of all pair-wise distances. It is
int minDiameter(vector<int> a, vector<int> b, int K) { const int INF = 1000000; int res = INF; int n = a.size() + 1; // the idea is we use bit masks to generate all subsets of a set of N // elements. Then we count the number of 1 bits so only those with K // elements are checked. for (int mask = 0; mask < (1<<n); mask++) { if (__builtin_popcount(mask) == K) { // One way to simplify implementation // The distances array. vector<vector<int>> dist(2*n, vector<int>(2*n, INF)); for (int i = 0; i < n; i++) { if (mask & (1<<i)) { //bridge dist[i][i + n] = 0; dist[i + n][i] = 0; } } // top for (int i = 0; i < n - 1; i++) { dist[i][i+1] = a[i]; dist[i+1][i] = a[i]; } // bottom for (int i = 0; i < n - 1; i++) { dist[i+n][i+n+1] = b[i]; dist[i+n+1][i+n] = b[i]; } // Floyd-Warshall for (int k = 0; k < 2*n; k++) { for (int i = 0; i < 2*n; i++) { for (int j = 0; j < 2*n; j++) { dist[i][j] = std::min( dist[i][j], dist[i][k] + dist[k][j]); } } } // Of known distances, pick the largest: int max_dist = 0; for (int i = 0; i < 2*n; i++) { for (int j = i + 1; j < 2*n; j++) { max_dist = std::max(max_dist, dist[i][j]); } } res = std::min(res, max_dist); } } return res; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
Floyd-Warshall+二进制枚举SRM 661 Div2 Medium: BridgeBuilding
原文地址:http://blog.csdn.net/acm_10000h/article/details/47061505
One example of an optimal solution is to draw the bridges as follows: