E
Time Limit: 1000MS Memory limit: 65536K
题目描述
给出一个带权无向图,求出其最小生成树。保证图连通。
输入
对于每组数据:
第一行输入n,m。表示此图有n(n <= 50000)个点,m(m <= 200000)条边。
接下来m行,每行u,v,w。表示u,v之间有一条权值为w的边。
第一行输入n,m。表示此图有n(n <= 50000)个点,m(m <= 200000)条边。
接下来m行,每行u,v,w。表示u,v之间有一条权值为w的边。
输出
对于每组数据,输出一个整数代表对应的最小生成树的权值和。
示例输入
3 5
1 2 1
1 3 2
2 3 4
2 3 5
1 3 1
示例输出
2
最小生成树,Kruskal 模板就能过。。关键在于路径压缩。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
const int inf=99999999;
struct node
{
int u;
int v;
int w;
} p[inf];
int bin[inf];
int cmp (const void *a,const void *b)
{
return (*(struct node*)a).w - (*(struct node *)b).w;
}
int fin(int x)
{
int k, j, r;
r = x;
while(r != bin[r])
r = bin[r];
k = x;
while(k != r)
{
j = bin[k];
bin[k] = r;
k = j;
}
return r;
}
int KKK (int n,int m)
{
int ans=0;
for (int i=0; i<=n; i++)
bin[i]=i;
for (int i=0; i<m; i++)
{
int uu=fin(p[i].u);
int vv=fin(p[i].v);
if (uu !=vv)
{
bin[uu]=vv;
// printf ("%d->%d %d\n",p[i].u,p[i].v,p[i].w);
ans+=p[i].w;
}
}
printf ("%d\n",ans);
return 0;
}
int main ()
{
int m,n;
while (~scanf ("%d%d",&n,&m))
{
for (int i=0; i<m; i++)
{
scanf ("%d %d %d",&p[i].u,&p[i].v,&p[i].w);
}
qsort (p,m,sizeof (p[0]),cmp);
KKK (n,m);
}
return 0;
}