您的位置:首页 > 其它

POJ 1258 Agri-Net 最小生成树 Prim 算法

2015-10-22 19:18 357 查看
Prim 算法描述

1).输入:一个加权连通图,其中顶点集合为V,边集合为E;

2).初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew =
{},为空;

3).重复下列操作,直到Vnew = V:

a.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);

b.将v加入集合Vnew中,将<u, v>边加入集合Enew中;

4).输出:使用集合Vnew和Enew来描述所得到的最小生成树
图例说明不可选可选已选(Vnew)




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




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




下一个顶点为距离D或A最近的顶点。B距D为9,距A为7,E为15,F为6。因此,F距D或A最近,因此将顶点F与相应边DF以高亮表示。C, GB, E, FA, D




算法继续重复上面的步骤。距离A为7的顶点B被高亮表示。CB, E, GA, D, F




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




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




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




现在,所有顶点均已被选取,图中绿色部分即为连通图的最小生成树。在此例中,最小生成树的权值之和为39。A, D, F, B, E, C, G
Prim算法的效率取决于结点数|v|,所以一般试用于稠密图。

Agri-Net

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 46318 Accepted: 19051
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

Source

USACO 102
[Submit]   [Go Back]   [Status]  
[Discuss]


Home Page   

Go
Back  

To top
裸最小生成树
//感谢bin巨的模板

ACcode:

#pragma warning(disable:4786)//使命名长度不受限制
#pragma comment(linker, "/STACK:102400000,102400000")//手工开栈
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <stack>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define rds(x) scanf("%s",x)
#define rdc(x) scanf("%c",&x)
#define ll long long int
#define maxn 105
#define mod 1000000007
#define INF 0x3f3f3f3f //int 最大值
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)
#define MT(x,i) memset(x,i,sizeof(x))
#define PI acos(-1.0)
#define E exp(1)
using namespace std;
bool vis[maxn];
int lowc[maxn];
int a[maxn][maxn];
int Prim(int cost[][maxn],int n){///点是1~n
int ans=0;
MT(vis,false);
vis[0]=true;
FOR(i,1,n-1)lowc[i]=cost[0][i];
FOR(i,1,n-1){
int minc=INF;
int p=-1;
FOR(j,0,n-1)
if(!vis[j]&&minc>lowc[j]){
minc=lowc[j];
p=j;
}
if(minc==INF)return -1;///原图不连接
ans+=minc;
vis[p]=true;
FOR(j,0,n-1)
if(!vis[j]&&lowc[j]>cost[p][j])
lowc[j]=cost[p][j];
}
return ans;
}
int main(){
int n;
while(rd(n)!=EOF){
FOR(i,0,n-1)
FOR(j,0,n-1)
rd(a[i][j]);
printf("%d\n",Prim(a,n));
}
return 0;
}
/*
4 0 4 9 21 4 0 8 17 9 8 0 16 21 17 16 0*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: