zoukankan      html  css  js  c++  java
  • hdu6166

    hdu6166

    题意

    给出一个有向图,选择 (k) 个点,问这 (k) 个点任意两点距离的最小值。

    分析

    按结点编号的二进制位,每次可以把所有点分到两个集合,那么求两个集合的点间的最短路即可( (0)作为源点,(n+1)作为汇点)。

    正确性的保证:编号的唯一性。任意两点一定存在某一次不在同一集合,二进制位一定有某一位不同。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, ll> P;
    const int MAXN = 1e5 + 10;
    const ll INF = 1e18 + 9;
    int n, m;
    struct node {
        int to, cost;
        node() {}
        node(int to, int cost) : to(to), cost(cost) {}
    };
    vector<node> G[MAXN];
    ll d[MAXN];
    ll dijkstra() {
        fill(d, d + MAXN, INF);
        priority_queue<P, vector<P>, greater<P> > q;
        d[0] = 0;
        q.push(P(0, 0));
        while(!q.empty()) {
            P u = q.top(); q.pop();
            if(d[u.second] < u.first) continue;
            for(int i = 0; i < G[u.second].size(); i++) {
                node nd = G[u.second][i];
                if(d[nd.to] > d[u.second] + nd.cost) {
                    d[nd.to] = d[u.second] + nd.cost;
                    q.push(P(d[nd.to], nd.to));
                }
            }
        }
        return d[n + 1];
    }
    int se[MAXN];
    int main() {
        int T, kase = 1;
        scanf("%d", &T);
        while(T--) {
            for(int i = 0; i <= n; i++) G[i].clear();
            scanf("%d%d", &n, &m);
            for(int i = 0; i < m; i++) {
                int u, v, c;
                scanf("%d%d%d", &u, &v, &c);
                G[u].push_back(node(v, c));
            }
            int k;
            scanf("%d", &k);
            for(int i = 0; i < k; i++) {
                scanf("%d", &se[i]);
            }
            ll ans = INF;
            for(int i = 0; i < 18; i++) {
                G[0].clear();
                for(int j = 0; j < k; j++) {
                    if((se[j] >> i) & 1) {
                        G[0].push_back(node(se[j], 0));
                    } else {
                        G[se[j]].push_back(node(n + 1, 0));
                    }
                }
                ans = min(ans, dijkstra());
                for(int j = 0; j < k; j++) {
                    if(!((se[j] >> i) & 1)) {
                        G[se[j]].pop_back();
                    }
                }
                G[0].clear();
                for(int j = 0; j < k; j++) {
                    if((se[j] >> i) & 1) {
                        G[se[j]].push_back(node(n + 1, 0));
                    } else {
                        G[0].push_back(node(se[j], 0));
                    }
                }
                ans = min(ans, dijkstra());
                for(int j = 0; j < k; j++) {
                    if((se[j] >> i) & 1) {
                        G[se[j]].pop_back();
                    }
                }
            }
            printf("Case #%d: %lld
    ", kase++, ans);
        }
        return 0;
    }
    
  • 相关阅读:
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    449. Serialize and Deserialize BST
    114. Flatten Binary Tree to Linked List
    199. Binary Tree Right Side View
    173. Binary Search Tree Iterator
    98. Validate Binary Search Tree
    965. Univalued Binary Tree
    589. N-ary Tree Preorder Traversal
    eclipse设置总结
  • 原文地址:https://www.cnblogs.com/ftae/p/7430094.html
Copyright © 2011-2022 走看看