最小生成树:
图中有好多点呀(n个),让我们找到n-1条边,来把他们连上吧,但是要让这n-1条边的和最小。
kruskal算法:
把所有边由升序排列,然后从最小的一条边找起,如果这条边的两点不属于一个集合(此处运用并查集),那么就要这条边,否则,忽略这条边吧~
一直这样找下去,直到找了n-1条边为止,此时,最小生成树出来了。
同理,可以求最大生成树。
code:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define MX 100000
struct point
{
int in,out;
int leth;
}eg[1000];
int n,m,pre[50];
bool cmp(point a,point b)
{
return a.leth<b.leth; //只要降序返回,即为最大生成树。
}
int find(int w)
{
int root=w,now;
while(root!=pre[root])
root=pre[root];
while(root!=pre[w])
{
now=pre[w];
pre[w]=root;
w=now;
}
return root;
}
int main()
{
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<=n;i++)
pre[i]=i;
for(int i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&eg[i].in,&eg[i].out,&eg[i].leth);
}
int sum=0,k=0;
sort(eg,eg+m,cmp);
for(int i=0;i<m;i++)
{
int x,y;
x=find(eg[i].in);
y=find(eg[i].out);
if(x!=y)
{
pre[y]=x;
sum+=eg[i].leth;
k++;
}
if(k==n-1)
break;
}
printf("%d\n",sum);
}
return 0;
}