一.原题链接: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);
}