hdu 1879——继续畅通工程 最小生成树

来源:互联网 发布:极域电子教室软件 编辑:程序博客网 时间:2024/05/19 13:25

hdu 1879 点击打开链接

若状态为1 则将两点归并

克鲁斯卡尔 算法:

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;int father[110],map[110][110];int ans,n;struct node{    int x,y;    int c;} s[5100];bool cmp(node a,node b){    return a.c<b.c;}int find(int i){    if(father[i]!=i)        father[i]=find(father[i]);    return father[i];}void merge(int a,int b){    a=find(a);b=find(b);    if(a>b)      father[a]=b;    else        father[b]=a;}void kru(){    for(int i=0; i<n*(n-1)/2; i++)    {        int a=find(s[i].x);        int b=find(s[i].y);        a=father[a];//使得father节点都为一个节点。        b=father[b];        if(a!=b)        {            ans+=s[i].c;            merge(a,b);        }    }}int main(){    int i,z,tem;    while(scanf("%d",&n)!=EOF)    {        if(n==0)            break;        for(i=0; i<=n; i++)            father[i]=i;        for(i=0; i<n*(n-1)/2; i++)        {            scanf("%d%d%d%d",&s[i].x,&s[i].y,&s[i].c,&z);            if(z==1)//在输入过程中即更新father数组            {                int xx=find(s[i].x);                int yy=find(s[i].y);                if(xx!=yy)                    merge(xx,yy);            }        }        sort(s,s+n*(n-1)/2,cmp);        ans=0;        kru();            printf("%d\n",ans);    }    return 0;}
prim算法:

#include<stdio.h>#include<string.h>int map[110][110],visit[11000],low[110];int n,ans;void prim(){    int pos,i,j,min=999999;    visit[1]=1;pos=1;    for(i=1;i<=n;i++)    {        if(i!=pos)            low[i]=map[pos][i];    }    for(i=1;i<n;i++)    {        min=99999999;        for(j=1;j<=n;j++)        {            if(visit[j]!=1&&min>low[j])            {                min=low[j];                pos=j;            }        }        visit[pos]=1;        ans+=low[pos];        for(j=1;j<=n;j++)        {            if(visit[j]!=1&&map[pos][j]<low[j])                low[j]=map[pos][j];        }    }}int main(){    int x,y,c,i,z;    while(scanf("%d",&n)!=EOF)    {        if(n==0)            break;        memset(map,0,sizeof(map));        memset(visit,0,sizeof(visit));        for(i=0;i<n*(n-1)/2;i++)        {            scanf("%d%d%d%d",&x,&y,&c,&z);            map[x][y]=map[y][x]=c;            if(z==1)                map[x][y]=map[y][x]=0;//key::不能用visit标记 否则在对low数组更新是会出问题!!!        }        ans=0;        prim();        printf("%d\n",ans);    }    return 0;}


0 0