【题目描述】
一个无向连通图的生成树是一个极小连通子图,它包括图中全部结点,并且有尽可能少的边。一棵生成树的代价是树中各条边上的代价之和。一个网络的各生成树中,具有最小代价的生成树称为该网络的最小代价生成树(minimum-cost spanning tree)。
【输入】
第一行输入结点个数n(n<100)和边的个数m,以下m行输入各边的两个结点u、v及该边上的代价。
【输出】
如果有生成树,则输出最小生成树的代价;如果没有生成树,则输出"no spanning tree"。
【输入样例】
6 10
1 2 10
1 4 30
1 5 45
2 3 50
2 5 40
2 6 25
3 5 35
3 6 15
4 6 20
5 6 55
【输出样例】
105
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define R register int
using namespace std;
int k,n,m,cnt,sum,ai,bi,ci,head[100],dis[100],vis[100];
struct Edge
{
int v,w,next;
}e[400005];
void add(int u,int v,int w)
{
e[++k].v=v;
e[k].w=w;
e[k].next=head[u];
head[u]=k;
}
typedef pair <int,int> pii;
priority_queue <pii,vector<pii>,greater<pii> > q;
void prim()
{
dis[1]=0;
q.push(make_pair(0,1));
while(!q.empty()&&cnt<n)
{
int d=q.top().first,u=q.top().second;
q.pop();
if(vis[u]) continue;
cnt++;
sum+=d;
vis[u]=1;
for(R i=head[u];i!=-1;i=e[i].next)
if(e[i].w<dis[e[i].v])
dis[e[i].v]=e[i].w,q.push(make_pair(dis[e[i].v],e[i].v));
}
}
int main()
{
memset(dis,127,sizeof(dis));
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(R i=1;i<=m;i++)
{
scanf("%d%d%d",&ai,&bi,&ci);
add(ai,bi,ci);
add(bi,ai,ci);
}
prim();
if (cnt==n)printf("%d",sum);
else printf("no spanning tree");
}