最小生成树(Prim/Kruskal)POJ 2395-Out of Hay

分手后的思念是犯贱 2022-05-15 11:56 179阅读 0赞
  • 最小生成树(Prim/Kruskal)POJ 2395-Out of Hay


  • 题目链接:

Out of Hay

  • 题目基础:最小生成树

最小生成树-Prim(普里姆)算法

最小生成树-Kruskal(克鲁斯卡尔)算法

  • 思路:

题目大意:

一个人从自己的农场出发,要访问N个农场,一共有M条路径(两个农场之间可能存在多条不等长路径),每个农场有水源,在路上需要消耗水,假设道路长length,需要length的水,这个人尽可能在总路径最短的情况下访问完所有农场,问在路上最多要带多少水

题解:

其实就是求最小生成树,只不过需要找出连接路径中最长的一条

坑:

在题目大意说了,“两个农场之间可能存在多条不等长路径”,因为我是用prim解,所以将数据输入邻接矩阵时需要比较下,kruskal就不必了

还有,起点是0,不是1

  • Prim解法代码:

    include

    include

    using namespace std;
    using namespace std;

    define INF 1000000007

    define MAX_SIZE 10005

    define Begin 1 //数组开头 1 or 0

    // Path[i]->i have lowest path:Path_low_cost[i]
    int Path[MAX_SIZE]; //结点i的父亲
    int Path_Low_Cost[MAX_SIZE]; //到达结点i的最小值
    int Vis[MAX_SIZE]; //标记已经进入最小树的结点
    int Min_Cost; //最短路径
    int Res; //标记最大值

    //邻接图
    struct MGrapth
    {

    1. int Vexs[MAX_SIZE]; //顶点表
    2. int Arc[MAX_SIZE][MAX_SIZE]; //邻接矩阵
    3. int Num_Vertext,Num_Edges; //顶点数,边数

    };

    MGrapth Map;

    void Init(int N,int M) //初始化
    {

    1. Res=-1;
    2. Min_Cost=0;
    3. Map.Num_Edges=M; //边数
    4. Map.Num_Vertext=N; //顶点数
    5. for(int i=0;i<=N;i++)
    6. for(int j=0;j<=N;j++)
    7. Map.Arc[i][j]=INF; //无穷大初始
    8. for(int i=0;i<=N;i++)
    9. {
    10. Path[i]=Path_Low_Cost[i]=INF;
    11. Map.Vexs[i]=i;
    12. Vis[i]=false;
    13. }

    }

    void Prim()
    {

    1. int Min,i,j,k;
    2. int End=Map.Num_Vertext+1; //结尾
    3. Path[Begin]=Begin; //Begin加入生成树
    4. Path_Low_Cost[Begin]=0;
    5. Vis[Begin]=true; //Begin已经加入
    6. for(i=Begin+1;i<End;i++)
    7. {
    8. Path_Low_Cost[i]=Map.Arc[Begin][i]; //首顶点与其他顶点的距离
    9. Path[i]=Begin;
    10. }
    11. for(int i=Begin+1;i<End;i++)
    12. {
    13. Min=INF;
    14. j=Begin+1,k=Begin;
    15. while(j<End)
    16. {
    17. if(!Vis[j]&&Path_Low_Cost[j]<Min)
    18. {
    19. Min=Path_Low_Cost[j];
    20. k=j;
    21. }
    22. j++;
    23. }
    24. Path_Low_Cost[k]=Min; //保存Path_Low_Cost[k] 到 k 的最短距
    25. Res=max(Res,Min); //保存路径最大值
    26. Vis[k]=true; //k加入最小生成树
    27. for(j=Begin+1;j<End;j++)
    28. {
    29. if(!Vis[j]&&Map.Arc[k][j]<Path_Low_Cost[j]) //如果 j 不在最小生成树内,并且 k到j有更小的路径,记录,更新
    30. {
    31. Path_Low_Cost[j]=Map.Arc[k][j];
    32. Path[j]=k;
    33. }
    34. }
    35. }

    }

    int main()
    {

    1. int N,M;
    2. while(cin>>N>>M)
    3. {
    4. Init(N,M);
    5. for(int i=0;i<M;i++)
    6. {
    7. int val,a,b;
    8. cin>>a>>b>>val;
    9. if(Map.Arc[a][b]>val)
    10. Map.Arc[a][b]=val;
    11. if(Map.Arc[b][a]>val)
    12. Map.Arc[b][a]=val;
    13. }
    14. Prim();
    15. cout<<Res<<endl;
    16. /*for(int i=Begin;i<=N;i++)
    17. cout<<Path[i]<<"---"<<i<<"---"<<Path_Low_Cost[i]<<endl;*/
    18. }
    19. return 0;

    }

发表评论

表情:
评论列表 (有 0 条评论,179人围观)

还没有评论,来说两句吧...

相关阅读

    相关 生成

    最小生成树定义: 在一给定的无向图 G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即![(u, v)\\in E][u_ v_in E]),而

    相关 生成

    有n个城市,m条道路,现在输入n到m的道路的长度,用最少的边将图连接,输出让图连接的最小值 这道题我研究了好长时间才把答案看明白,现在给大家分享一下 具体代码如下

    相关 生成

    问题提出: 要在n个城市间建立通信联络网。顶点:表示城市,权:城市间通信线路的花费代价。希望此通信网花费代价最小。 问题分析: 答案只能从生成树中找,因为要做到任何