图结构练习——最小生成树
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
最小生成树:
题目描述
有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的。现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市。
输入
输入包含多组数据,格式如下。
第一行包括两个整数n m,代表城市个数和可以修建的公路个数。(n <= 100, m <=1000)
剩下m行每行3个正整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c。
输出
每组输出占一行,仅输出最小花费。
示例输入
3 2 1 2 1 1 3 1 1 0
示例输出
2 0
提示
基于临建矩阵的prim
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<iomanip>
#include<climits>
#include<set>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<cstdlib>
#include<iostream>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 110;
int mp[N][N];
int dis[N];
bool vis[N];
int m,n;
void prim()
{
for(int i=1; i<=n; i++)
{
dis[i]=mp[1][i]; //dis数组记录到某点的最短距离;
vis[i]=0;
}
vis[1]=1; //假设从1点出发;最小生成树的形成与起点无关;
int sum=0,mm,pos;
for(int i=1; i<n; i++) //n个点,n-1条边可构成生成树;
{
mm=INF;
for(int j=1; j<=n; j++)
{
if(dis[j]<INF&&!vis[j]&&dis[j]<mm) //每次选择最小的边;
{
mm=dis[pos=j];
}
}
sum+=mm;
vis[pos]=1;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]>mp[pos][j]) //有最短点更新到某点最短距离;
dis[j]=mp[pos][j];
}
}
cout<<sum<<endl;
}
int main()
{
int u,v,w;
while(cin>>n>>m)
{
for(int i=1; i<=n; i++) //初始化,任意相异两点之间不可达;
{
for(int j=1; j<=n; j++)
if(i!=j)mp[i][j]=INF;
else
mp[i][j]=0;
}
for(int i=0; i<m; i++)
{
cin>>u>>v>>w;
if(mp[u][v]>w) //更新所给两点间的距离;(去最小)
mp[u][v]=mp[v][u]=w;
}
prim();
}
return 0;
}
krustra 算法;
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cctype>
#include<iomanip>
#include<climits>
#include<set>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<cstdlib>
#include<iostream>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N = 110;
int mp[N][N];
int dis[N];
bool vis[N];
int m,n;
struct Edge
{
int u,v,w;
bool operator < (const Edge& x)const
{
return w<x.w;
}
};
int fa[N];
int fint(int x)
{
return fa[x]!=x?fa[x]=fint(fa[x]):x;
}
vector<Edge>V;
int main()
{
Edge tmp;
int g,h;
vector<Edge>::iterator iter;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
}
V.clear();
for(int i=0; i<m; i++)
{
cin>>tmp.u>>tmp.v>>tmp.w;
V.push_back(tmp);
}
sort(V.begin(),V.end());
int sum=0,cnt=0;
for(iter=V.begin();iter!=V.end();iter++)
{
g=fint(iter->u);h=fint(iter->v);
if(g!=h)
{
fa[g]=h;
cnt++;
sum+=iter->w;
if(cnt==n-1)
break;
}
}
cout<<sum<<endl;
}
return 0;
}