POJ1751 Highways

一.原题链接:http://poj.org/problem?id=1751

二.题目大意:首先给出N个城市的坐标,再给出哪些城市已经相互连通,求花费最少的路,将所有城市连通,输出需要连通的城市。

三.思路:刚开始想用Kruskal做比较方便,因为它分开后森林,而且每课树的节点不唯一。但是还是练习一下Prim输出节点,其实只要把已经连通的城市的权置为0,然后在输出的时候先判断这条路的权值是不是为0,不是才输出,就可以了。

四.代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;

const int MAX_SIZE = 755,
          INF = 0x3f3f3f3f,
          MOD = 1000000007;

int nodeNum, builtNum, nearVex[MAX_SIZE];
double x[MAX_SIZE], y[MAX_SIZE];
double graph[MAX_SIZE][MAX_SIZE], lowCost[MAX_SIZE];

void init()
{
    int i, j, cityA, cityB;

    cin>>nodeNum;

    for(i = 1; i <= nodeNum; i++)
        cin>>x[i]>>y[i];

    for(i = 1; i <= nodeNum; i++){
        for(j = i + 1; j <= nodeNum; j++)
            graph[j][i] = graph[i][j] =
            sqrt(pow(x[i] - x[j], 2.0) + pow(y[i] - y[j], 2.0) );
    }
    cin>>builtNum;

    for(i = 1; i <= builtNum; i++){
        cin>>cityA>>cityB;
        graph[cityA][cityB] = graph[cityB][cityA] = 0;
    }
}

void Prim(int start)
{
    int i, j, v;
    double minEdge;
    for(i = 1; i <= nodeNum; i++){
        lowCost[i] = graph[start][i];
        nearVex[i] = start;
    }

    nearVex[start] = -1;

    for(i = 1; i < nodeNum; i++){
        minEdge = INF;
        v = -1;
        for(j  = 1; j <= nodeNum; j++)
            if(nearVex[j] != -1 && lowCost[j] < minEdge){
                minEdge = lowCost[j];
                v = j;
            }

        if(graph[v][nearVex[v]] != 0.0)
            cout<<nearVex[v]<<" "<<v<<endl;

        nearVex[v] = -1;

        for(j = 1; j <= nodeNum; j++)
            if(nearVex[j] != -1 && lowCost[j] > graph[v][j]){
                lowCost[j] = graph[v][j];
                nearVex[j] = v;
            }
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);

    init();

    Prim(1);
}


你可能感兴趣的:(POJ1751 Highways)