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

POJ #2485 Highways MST中的最大边权

时间:2018-02-24 20:53:11      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:估计   poj   empty   algo   case   ++   ace   set   display   

Description


 

  问题描述:链接

 

思路


 

  题目很直接,容易看出建的图是一张完全图,需要求出图中最小生成树的最大边权。由于数据上界已经定死了,那么选择用静态邻接表存建图。由于图是稠密图,那么求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\n", ans);
    }
    return 0;
}
View Code

 

POJ #2485 Highways MST中的最大边权

标签:估计   poj   empty   algo   case   ++   ace   set   display   

原文地址:https://www.cnblogs.com/Bw98blogs/p/8467422.html

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