模板整理——图论·最小生成树·Kruskal

来源:互联网 发布:mysql数据库ip怎么查询 编辑:程序博客网 时间:2024/06/06 00:36

思想:把所有边按权值从小到大排序,每次取最小的未处理边e,若e连接的两个点u,v不在同一集合,则将e加入最小生成树,将u,v放入同一集合(并查集),一共需要加入n-1条边

时间复杂度:O(mlgm)

#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;int fa[105];struct node{    int u,v,l;}e[105];bool cmp(node t1,node t2){    return t1.l<t2.l;}int Find(int u){    if (u==fa[u]) return u;    fa[u]=Find(fa[u]);    return fa[u];}void Union(int u,int v){    int x=Find(u),y=Find(v);    fa[y]=x;}int main(){    int n,m;    scanf("%d%d",&m,&n);    while (m!=0)    {        int num=0;        for (int i=1; i<=n; i++) fa[i]=i;        memset(e,0,sizeof(e));        for (int i=1; i<=m; i++)         {            int u,v,l;            scanf("%d%d%d",&u,&v,&l);            e[++num].u=u;            e[num].v=v;            e[num].l=l;        }        sort(e+1,e+1+num,cmp);        int s=0,ans=0;        for (int i=1; i<=num; i++)        {            int u=e[i].u,v=e[i].v;            if (Find(u)!=Find(v))             {                s++;                Union(u,v);                ans+=e[i].l;                if (s==n-1) break;             }        }        if (s<n-1) printf("?\n");        else printf("%d\n",ans);        scanf("%d%d",&m,&n);    }    return 0;}

代码是这题的–>__–>HDU1863畅通工程