码迷,mamicode.com
首页 > 其他好文 > 详细

Floyd-Warshall+二进制枚举SRM 661 Div2 Medium: BridgeBuilding

时间:2015-07-26 00:35:52      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:binary_function   srm661   最短路   

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 ab, 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{ 1, 50, 1, 50, 1, 50, 1, 50 }
    • b{ 50, 1, 50, 1, 50, 1, 50, 1 }
    • K9
    Returns8
    • 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{ 2, 4, 10, 2, 2, 22, 30, 7, 28 }
    • b{ 5, 26, 1, 2, 6, 2, 16, 3, 15 }
    • K5
    Returns54
题解

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;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

Floyd-Warshall+二进制枚举SRM 661 Div2 Medium: BridgeBuilding

标签:binary_function   srm661   最短路   

原文地址:http://blog.csdn.net/acm_10000h/article/details/47061505

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!