poj--1258

---恢复内容开始---

Description

Farmer John has been elected mayor of his town! One of his campaign promises was to bring internet connectivity to all farms in the area. He needs your help, of course. 
Farmer John ordered a high speed connection for his farm and is going to share his connectivity with the other farmers. To minimize cost, he wants to lay the minimum amount of optical fiber to connect his farm to all the other farms. 
Given a list of how much fiber it takes to connect each pair of farms, you must find the minimum amount of fiber needed to connect them all together. Each farm must connect to some other farm such that a packet can flow from any one farm to any other farm. 
The distance between any two farms will not exceed 100,000. 

Input

The input includes several cases. For each case, the first line contains the number of farms, N (3 <= N <= 100). The following lines contain the N x N conectivity matrix, where each element shows the distance from on farm to another. Logically, they are N lines of N space-separated integers. Physically, they are limited in length to 80 characters, so some lines continue onto others. Of course, the diagonal will be 0, since the distance from farm i to itself is not interesting for this problem.

Output

For each case, output a single integer length that is the sum of the minimum length of fiber required to connect the entire set of farms.

Sample Input

4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0

Sample Output

28

题目大意:John要为农场安装光纤,每个农场都要安装,要求最小的光纤数

题解 :依据题意可以知道本题是最小生成树,用prim解法

Prim算法:最小生成树,且没有环,也就是说节点不会通过其他节点(或者自身)回到本节点

图例说明不可选可选已选(Vnew
 

此为原始的加权连通图。每条边一侧的数字代表其权值。 - - -

顶点D被任意选为起始点。顶点ABEF通过单条边与D相连。A是距离D最近的顶点,因此将A及对应边AD以高亮表示。 C, G A, B, E, F D
 

下一个顶点为距离DA最近的顶点。BD为9,距A为7,E为15,F为6。因此,FDA最近,因此将顶点F与相应边DF以高亮表示。 C, G B, E, F A, D
算法继续重复上面的步骤。距离A为7的顶点B被高亮表示。 C B, E, G A, D, F
 

在当前情况下,可以在CEG间进行选择。CB为8,EB为7,GF为11。E最近,因此将顶点E与相应边BE高亮表示。 C, E, G A, D, F, B
 

这里,可供选择的顶点只有CGCE为5,GE为9,故选取C,并与边EC一同高亮表示。 C, G A, D, F, B, E

顶点G是唯一剩下的顶点,它距F为11,距E为9,E最近,故高亮表示G及相应边EG G A, D, F, B, E, C

现在,所有顶点均已被选取,图中绿色部分即为连通图的最小生成树。在此例中,最小生成树的权值之和为39。 A, D, F, B, E, C, G



上图摘自维基百科

下面附上代码注释中有解说

/*poj 1258 --prim最小生成树*/
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int INF=1e9;
const int N=10000+10;
int farm[N][N];
int dist[N];
bool visited[N];
int ans,n;
void Prim()
{
    int i,j,k;
    for(i=1;i<=n;i++)
    {
        dist[i]=INF;
        visited[i]=false;
    }
    dist[1]=0;ans=0;
    for(i=1;i<=n;i++)
    {
        int temp=INF;
        for(j=1;j<=n;j++)  //遍历一遍找到距离上一节点最短的j 
        {
            if(!visited[j]&&dist[j]<temp)//标记visited[]保证不会形成环 
            {
                temp=dist[j];
                k=j;
            }
        }
        visited[k]=true;
        ans+=temp;
        for(j=1;j<=n;j++)
        {
            if(!visited[j]&&dist[j]>farm[k][j])//在从这个节点开始寻找下面节点
                dist[j]=farm[k][j];
        }
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                scanf("%d",&farm[i][j]);
            }
        Prim();
        printf("%d
",ans);
    }
    return 0;
}




---恢复内容结束---

原文地址:https://www.cnblogs.com/acmblog/p/9561263.html