Highways---poj1751最小生成树

http://poj.org/problem?id=1751

题意:有n个点,已知各点坐标,距离为权值,求最小生成树的边

但是这个最小生成树的m条边是已经确定的了,所以可以让已知边的权值为0;

在Prim算法中改一下就行

#include<stdio.h>
#include<string.h>
#include<map>
#include<iostream>
#include<algorithm>
#include<math.h>
#define N 1100
#define INF 0xfffffff

using namespace std;

int vis[N], n, pre[N];//pre[i]记录的是i的父节点;
double maps[N][N],dist[N];

void Prim(int start)
{
    vis[start] = 1;
    for(int i=1; i<=n; i++)
    {
        dist[i] = maps[start][i];
        pre[i] = start;
    }
    for(int i=1; i<=n; i++)
    {
        double Min = INF;
        int index = -1;
        for(int j = 1; j <= n; j++)
        {
            if(vis[j]==0 && Min>dist[j])
            {
                Min = dist[j];
                index = j;
            }
        }
        if(index == -1) break;
        if(Min != 0)
            printf("%d %d
", pre[index],index);
        vis[index] = 1;
        for(int j=1; j<=n; j++)
        {
            if(vis[j]==0 && dist[j] > maps[index][j])
                dist[j] = maps[index][j], pre[j] = index;
        }
    }
}

struct node
{
    int x, y;
}a[N];

void Init()
{
    for(int i=0;i<=n;i++)
    {
        pre[i] = i;
        vis[i] = 0;
        dist[i] = INF;
        for(int j=0; j<=n; j++)
            maps[i][j] = INF;
        maps[i][i] = 0;
    }
}

int main()
{
    int i, j, x, y, m;
    double d;
    while(scanf("%d", &n)!=EOF)
    {
        Init();
        memset(a,0,sizeof(a));
        for(i=1;i<=n;i++)
            scanf("%d%d", &a[i].x, &a[i].y);
        for(i=1; i<=n; i++)
        {
            for(j=i+1; j<=n; j++)
            {
                d = sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
                maps[i][j] = maps[j][i] = d;
            }
        }
        scanf("%d", &m);
        for(i=0; i<m; i++)
        {
            scanf("%d%d", &x,&y);
            maps[x][y] = maps[y][x] = 0; //把已知边的权值置为0;   
        }
        Prim(1);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4682089.html