数据结构实验之图论六:村村通公路
Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic DiscussProblem Description
当前农村公路建设正如火如荼的展开,某乡镇*决定实现村村通公路,工程师现有各个村落之间的原始道路统计数据表,表中列出了各村之间可以建设公路的若干条道路的成本,你的任务是根据给出的数据表,求使得每个村都有公路连通所需要的最低成本。Input
连续多组数据输入,每组数据包括村落数目N(N <= 1000)和可供选择的道路数目M(M <= 3000),随后M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个村庄的编号和修建该道路的预算成本,村庄从1~N编号。Output
输出使每个村庄都有公路连通所需要的最低成本,如果输入数据不能使所有村庄畅通,则输出-1,表示有些村庄之间没有路连通。Example Input
5 8
1 2 12
1 3 9
1 4 11
1 5 3
2 3 6
2 4 9
3 4 4
4 5 6
Example Output
19
注:加权无向图
学习新知: ①:树(tree)是没有环的图。可以说树一种特殊的图,在树中,任意顶点r和顶点v必然存在着一条路径。若顶点有n个,那么最小生成树的边有n-1条。最小生成树(Minimum Spanning Tree)就是指各边权值最小的生成树,即最小生成树是图的子图。 ②:普利姆算法(Prim's Algorithm)是求最小生成树(MST)的代表性算法之一。 ③:通过学习,自己深深感觉到Prim算法(最小生成树)和dijkstra算法(最短路径)有异曲同工之妙!参考资料: 最小生成树Prim算法理解:http://blog.csdn.net/yeruby/article/details/38615045
AC代码:
#include<iostream>
#include<cstring>
#define INF 0x3f3f3f3f
#define MAX 1005
using namespace std;
int mmap[MAX][MAX];
bool vis[MAX];
int dist[MAX];
int prim(int n) //普里姆算法求图的最小生成树(MST)
{
for(int i=1;i<=n;i++)
dist[i]=mmap[1][i];
vis[1]=true;
int k;
int mmin;
int sum=0;
for(int i=1;i<n;i++)
{
mmin=INF;
for(int j=1;j<=n;j++)
{
if(!vis[j] && dist[j]<mmin)
{
mmin=dist[j];
k=j;
}
}
sum+=mmin;
vis[k]=true;
if(mmin==INF)
return -1;
for(int j=1;j<n;j++)
{
if(!vis[j] && mmap[k][j]<dist[j])
dist[j]=mmap[k][j];
}
}
return sum;
}
int main()
{
int n,m;
while(cin>>n>>m)
{
int u,v,w;
memset(mmap,0,sizeof(mmap));
memset(vis,false,sizeof(vis));
memset(dist,0,sizeof(dist));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
mmap[i][j]=0;
else
mmap[i][j]=INF;
}
}
while(m--)
{
cin>>u>>v>>w;
if(w<mmap[u][v])
{
mmap[u][v]=mmap[v][u]=w;
}
}
cout<<prim(n)<<endl;
}
return 0;
}