zoukankan      html  css  js  c++  java
  • POJ #2485 Highways MST中的最大边权

    Description


    The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're planning to build some highways so that it will be possible to drive between any pair of towns without leaving the highway system. 


    Flatopian towns are numbered from 1 to N. Each highway connects exactly two towns. All highways follow straight lines. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways. 

    The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.

    Input

    The first line of input is an integer T, which tells how many test cases followed. 
    The first line of each case is an integer N (3 <= N <= 500), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 65536]) between village i and village j. There is an empty line after each test case.

    Output

    For each test case, you should output a line contains an integer, which is the length of the longest road to be built such that all the villages are connected, and this value is minimum.

    Sample Input

    1
    
    3
    0 990 692
    990 0 179
    692 179 0

    Sample Output

    692
    

    Hint

    Huge input,scanf is recommended.

    思路


      题目很直接,容易看出建的图是一张完全图,需要求出图中最小生成树的最大边权。由于数据上界已经定死了,那么选择用静态邻接表存建图。由于图是稠密图,那么求MST的话就选择 prim 。

      做完 POJ #2253 Frogger 变种Dijkstra 后再做这个就很有感觉了。其实prim中的核心操作就是记录并更新点v到树的最短距离,然后把所有最短距离之中的最小值选出,将该点其加入树集。这个树集与dijkstra中的点集是异曲同工的。

      能用 scanf 的话尽量用 scanf 吧,比 cin 快很多。

    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define INF 0x3f3f3f3f
    const int MAXN = 510;
    const int EDGE_MAXN = 250010;
    int n;
    //链式前向星
    struct Edge {
        int to;
        int w; //2^31-1 > 65536
        int next;
    }e[EDGE_MAXN];
    int head[MAXN], cnt;
    
    void addEdge (int u, int v, int w) {
        cnt++;
        e[cnt].to = v;
        e[cnt].w = w;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    
    void initG() {
        memset(head, -1, sizeof(head));
        cnt = 0;
        scanf ("%d", &n);
        for (int i = 1; i <= n; i++) {
            int tmp;
            for (int j = 1; j <= i-1; j++) {
                scanf ("%d", &tmp);
                addEdge(i, j , tmp);
            }
            scanf ("%d", &tmp); // i = j 形成自环,对建图并没有用
            for (int j = i+1; j <= n; j++) {
                scanf ("%d", &tmp);
                addEdge(i, j, tmp);
            }
        }
    }
    
    //求最小生成树的最大边权
    struct Node{
        int id;
        int key;
        Node(int v, int w) : id(v), key(w) {}
        friend bool operator < (const Node& a, const Node& b) {
            return a.key > b.key;
        }
    };
    int d[MAXN]; //v到树的最短距离估计值
    int vis[MAXN];
    void prim (const int& s, int& max) {
        for (int i = 1; i <= n; i++) d[i] = INF, vis[i] = false;
        d[s] = 0;
        priority_queue <Node> pq;
        pq.push(Node(s, d[s]));
        while (!pq.empty()) {
            int u = pq.top().id; pq.pop();
            if (vis[u]) continue;
            vis[u] = true;
            if (max < d[u]) max = d[u];
            for (int i = head[u]; i != -1; i = e[i].next) {
                int v = e[i].to;
                if (!vis[v] && d[v] > e[i].w) {
                    d[v] = e[i].w; //更新v到树的最短距离
                    pq.push (Node(v, d[v]));
                }
            }
        }
    }
    
    int main(void) {
        int case_num;
        cin >> case_num;
        while (case_num--) {
            initG();
            int ans = 0;
            prim(1, ans);
            printf ("%d
    ", ans);
        }
        return 0;
    }
    View Code
    ————全心全意投入,拒绝画地为牢
  • 相关阅读:
    15_门面模式
    14_责任链模式
    13_观察者模式
    12_状态模式
    11_策略模式
    10_命令模式
    09_适配器模式
    08_装饰者模式
    07_代理模式
    linux邮件服务器postfix配置实例
  • 原文地址:https://www.cnblogs.com/Bw98blogs/p/8467422.html
Copyright © 2011-2022 走看看