最小生成树+并查集模板

来源:互联网 发布:软件配置管理人员职责 编辑:程序博客网 时间:2024/04/28 10:56

hdu 1233 hdu 1102 poj  1789 hdu 1301     hdu 2682

模板:

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<iostream>#define inf 0x3f3f3f3fusing namespace std;int a[601][601];int dis[601],vis[601],n,m,k;int f[601];int find(int t)//并查集判断是否连通{    if(f[t]==-1) return t;    return f[t]=find(f[t]);}void bing(int a,int b){    int t1=find(a);    int t2=find(b);    if(t1!=t2) f[t1]=t2;}int prim()//普里姆算法{    int sum=0,i,j,k=0,minn;    memset(vis,0,sizeof(vis));    for(i=0; i<n; i++)    {        dis[i]=a[0][i];        vis[i]=0;    }    vis[0]=1;    for(i=0; i<n-1; i++)    {        minn=inf;        for(j=0; j<n; j++)        {            if(vis[j]==0&&dis[j]<minn)            {                minn=dis[j];                k=j;            }        }        sum+=minn;        vis[k]=1;        for(j=0; j<n; j++)        {            if(vis[j]==0&&dis[j]>a[k][j])  dis[j]=a[k][j];        }    }    return sum;}int main(){    while(scanf("%d%d",&m,&n),m!=0)    {        int i,x,y,d;        memset(a,inf,sizeof(a));        for(i=0; i<n; i++)            a[i][i]=0;        for(i=1;i<=n;i++)            f[i]=-1;        for(i=0; i<m; i++)        {            scanf("%d%d%d",&x,&y,&d);            bing(x,y);            a[x-1][y-1]=a[y-1][x-1]=d;        }        int res=0;        for(i=1;i<=n;i++)        {            if(f[i]==-1) res++;        }        //printf("%d\n",res);//只能        if(prim()==0||prim()==inf||res>1)            printf("?\n");        else            printf("%d\n",prim());    }}



2 0
原创粉丝点击