HDU 1102 Constructing Roads

链接 : http://acm.hdu.edu.cn/showproblem.php?pid=1102


最小生成树,Prim和Kruskal,与1233相比变一个输入方式

正因如此,Kruskal算法想了半天也没想出来什么好的记录边的方法,最后直接先用数组保存,再把数组的数据转换成边的形式

不是什么聪明的办法,最后也算AC了


Prim:

#include <cstdio>
#include <climits>
#include <cstring>
using namespace std;
int map[110][110];
bool used[110];
int Prim(int n)
{
    int sum=0,T=n-1;
    while(T--)
    {
        int mini=INT_MAX,t;
        for(int i=2; i<=n; i++)
            if(!used[i] && mini>map[1][i])
            {
                mini=map[1][i];
                t=i;
            }
        sum+=mini;
        used[t]=1;
        for(int i=2; i<=n; i++)
            if(!used[i] && map[t][i]<map[1][i])
                map[1][i]=map[t][i];
    }
    return sum;
}
int main()
{
    int n,q;
    while(~scanf("%d",&n))
    {
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                scanf("%d",&map[i][j]);
        scanf("%d",&q);
        while(q--)
        {
            int x,y;
            scanf("%d %d",&x,&y);
            map[x][y]=map[y][x]=0;
        }
        memset(used,0,sizeof(used));
        printf("%d\n",Prim(n));
    }
    return 0;
}


Kruskal:

#include <cstdio>
#include <algorithm>
using namespace std;
struct node
{
    int b,e,dis;
}s[5001];
int father[101],map[101][101];
bool cmp(node a,node b)
{
    return a.dis<b.dis;
}
int find(int n)
{
    return n==father[n] ? n : father[n]=find(father[n]);
}
int Kruskal(int n)
{
    for(int i=0;i<101;i++) father[i]=i;
    sort(s,s+n,cmp);
    int sum=0;
    for(int i=0;i<n;i++)
    {
        int x=find(s[i].b);
        int y=find(s[i].e);
        if(x!=y)
        {
            father[y]=x;
            sum+=s[i].dis;
        }
    }
    return sum;
}
int main()
{
    int n,q,x,y,k;
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                scanf("%d",&map[i][j]);
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d %d",&x,&y);
            map[x][y]=map[y][x]=0;
        }
        k=0;
        for(int i=1;i<=n;i++) //转换成边
            for(int j=i+1;j<=n;j++)
            {
                s[k].b=i;
                s[k].e=j;
                s[k++].dis=map[i][j];
            }
        printf("%d\n",Kruskal(k));
    }
    return 0;
}



你可能感兴趣的:(最小生成树,Prim算法,kruskal算法,hdu1102)