SRM 661-Medium: BridgeBuildingDiv2
Problem Statement
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.
Definition
- ClassBridgeBuildingDiv2
- MethodminDiameter
- Parametersvector<int> , vector<int> , int
- Returnsint
- Method signatureint minDiameter(vector<int> a, vector<int> b, int K)
(be sure your method is public)
Limits
- Time limit (s)2.000
- Memory limit (MB)256
Constraints
- N will be between 2 and 11, inclusive.
- a,b will contain exactly N-1 elements each.
- K will be between 1 and N, inclusive.
- Each element of a,b will be between 1 and 50, inclusive.
Test cases
-
- a{ 2, 1, 1, 1,
2 } - b{ 1, 9, 1, 9,
1 } - K4
Returns6
One example of an optimal solution is to draw the bridges as follows:
- a{ 2, 1, 1, 1,
-
- a{ 1, 50, 1, 50,
1, 50, 1, 50 } - b{ 50, 1, 50, 1,
50, 1, 50, 1 } - K9
Returns8
- a{ 1, 50, 1, 50,
-
- a{ 50, 10, 15,
31, 20, 23, 7, 48, 5, 50 } - b{ 2, 5, 1, 8,
3, 2, 16, 11, 9, 1 } - K3
Returns124
- a{ 50, 10, 15,
-
- a{ 2, 4, 10, 2,
2, 22, 30, 7, 28 } - b{ 5, 26, 1, 2,
6, 2, 16, 3, 15 } - K5
Returns54
- a{ 2, 4, 10, 2,
题解
All bridges must be vertical. This means that there are only
N possible
locations for the bridges. With a given K,
this leads to(NK) (Where (NK)is
the binomial coefficient) total options for ways to assign K bridges
to N positions.
For N=11,K=6
(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
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 O(|V|3) ,
which we repeat for each of the (at most 462) options for sets. Note that the number of vertices |V| is
actually 2N,
this means that |V|3 is 8N3.
It is still very appropriate given the small constraints.
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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。