klkkhelllo 2020-02-06 14:57 采纳率: 40%
浏览 225
已结题

假设一个图的边的权值都在1到n的整数范围内,如何设计出一种算法来找出这个图的最小生成树呢?

V代表点,E代表边,假设一个图的边的权值都在**1到n的整数范围**内,如何设计出一种**O(n(V+E))**的算法来找出这个图的最小生成树呢?有没有办法通过修改kruskal算法来得到O(n(V+E))时间复杂度呢?如果没法修改,有没有其它的算法可以达到O(n(V+E))?
不用写代码,只要给出具体算法思路即可,感谢!!

  • 写回答

1条回答 默认 最新

  • dabocaiqq 2020-02-06 15:03
    关注
    #include <stdio.h>
    #include <stdlib.h>
    #define Max 50
    typedef struct road *Road;
    typedef struct road
    {
        int a , b;
        int w;
    }road;
    
    typedef struct graph *Graph;
    typedef struct graph
    {
        int e , n;
        Road data;
    }graph;
    
    Graph initGraph(int m , int n)
    {
        Graph g = (Graph)malloc(sizeof(graph));
        g->n = m;
        g->e = n;
        g->data = (Road)malloc(sizeof(road) * (g->e));
        return g;
    }
    
    void create(Graph g)
    {
        int i;
        for(i = 1 ; i <= g->e ; i++)
        {
            int x , y, w;
            scanf("%d %d %d",&x,&y,&w);
            if(x < y)
            {
                g->data[i].a = x;
                g->data[i].b = y;
            }
            else
            {
                g->data[i].a = y;
                g->data[i].b = x;
            }
            g->data[i].w = w;
        }
    }
    
    int getRoot(int v[], int x)
    {
        while(v[x] != x)
        {
            x = v[x];
        }
        return x;
    }
    
    void sort(Road data, int n)
    {
        int i , j;
        for(i = 1 ; i <= n-1 ; i++)
        {
            for(j = 1 ; j <= n-i ; j++)
            {
                if(data[j].w > data[j+1].w)
                {
                    road t = data[j];
                    data[j] = data[j+1];
                    data[j+1] = t;
                }
            }
        }
    }
    
    int Kruskal(Graph g)
    {
        int sum = 0;
        //并查集
        int v[Max];
        int i;
        //init
        for(i = 1 ; i <= g->n ; i++)
        {
            v[i] = i;
        }
        sort(g->data , g->e);
        //main
        for(i = 1 ; i <= g->e ; i++)
        {
            int a , b;
            a = getRoot(v,g->data[i].a);
            b = getRoot(v,g->data[i].b);
            if(a != b)
            {
                v[a] = b;
                sum += g->data[i].w;
            }
        }
        return sum;
    }
    
    int main()
    {
        int m , n , id = 1;
        while(scanf("%d %d",&m,&n) != EOF)
        {
            int r , i;
            Graph g = initGraph(m,n);
            create(g);
            r = Kruskal(g);
            printf("Case %d:%d\n",id++,r);
            free(g);
        }
        return 0;
    }
    
    

    https://blog.csdn.net/mgsky1/article/details/77840286

    评论

报告相同问题?

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站