zoukankan      html  css  js  c++  java
  • 最小树形图——朱刘算法

    首先问一个问题  最小生成树是用来解决有向图还是无向图问题的

    最小生成树详解  见     https://blog.csdn.net/ZCY19990813/article/details/81503525

    。。。。要是你回答无向图的话  可以往下面看啦

    最小树形图是用来解决有向图的最小生成树问题(unidirectional 单向的)

    性质:最小树形图基于贪心和缩点的思想。

    正在看这篇文章    https://blog.csdn.net/lianai911/article/details/45462361

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<limits.h>
    using namespace std;
    const int MAXN = 110;
    const int MAXM = 10010;
    
    struct Node//存放图
    {
        int from;
        int to;
        double w;
    }Edges[MAXM];
    
    struct Node1
    {
        double x;
        double y;
    };
    Node1 Point[MAXN];
    
    double Dist(Node1 a, Node1 b)
    {
        double x = a.x - b.x;
        double y = a.y - b.y;
        return sqrt(x*x+y*y);
    }
    
    int pre[MAXN],vis[MAXN],flag[MAXN];
    //flag标记缩点,标记为true,则该点被缩掉
    double In[MAXN],sum;
    
    double ZhuLiu(int root,int N,int M)
    {
        sum = 0;    //存放最小树形图
        while(true)
        {
            //求最短弧集合
            for(int i = 0; i < N; ++i)
                In[i] = INT_MAX;
            for(int i = 0; i < M; ++i)
            {
                int u = Edges[i].from;
                int v = Edges[i].to;
                if(Edges[i].w < In[v] && u != v)
                {
                    pre[v] = u;//v为终点,pre[v]存放起点
                    In[v] = Edges[i].w;//权值最小的边
                }
            }
    
            for(int i = 0; i < N; ++i)//如果存在除root以外的孤立点,则不存在最小树形图
            {
                if(i == root)
                    continue;
                if(In[i] == INT_MAX)
                    return -1;
            }
            int CntNode = 0;    //新图编号
            memset(flag,-1,sizeof(flag));
            memset(vis,-1,sizeof(vis));
            In[root] = 0;
            for(int i = 0; i < N; ++i)   //找环,标记每个环
            {
                sum += In[i];
                int v = i;
                while(vis[v]!=i && flag[v]==-1 && v!=root)//每个点寻找其前序点,要么最终寻找至根部,要么找到一个环
                {
                    vis[v] = i;
                    v = pre[v];
                }
                if(v != root && flag[v] == -1)  //新图重新编号
                {
                    for(int u = pre[v]; u != v; u = pre[u])
                        flag[u] = CntNode;
                    flag[v] = CntNode++;
                }
            }
            if(CntNode == 0)    //无环,跳出
                break;
            for(int i = 0; i < N; ++i)  //缩点
            {
                if(flag[i] == -1)
                    flag[i] = CntNode++;
            }
            for(int i = 0; i < M; ++i)  //建立新图,更新其他点到环的距离
            {
                int v = Edges[i].to;
                Edges[i].from = flag[Edges[i].from];
                Edges[i].to = flag[Edges[i].to];
                if(Edges[i].from != Edges[i].to)
                    Edges[i].w -= In[v];
            }
            N = CntNode;
            root = flag[root];
        }
        return sum;
    }
    
    int main()
    {
        int x,y,N,M;
        while(~scanf("%d%d",&N,&M))
        {
            int id = 0;
            for(int i = 0; i < N; ++i)
                scanf("%lf%lf",&Point[i].x,&Point[i].y);
            for(int i = 0; i < M; ++i)
            {
                scanf("%d%d",&x,&y);
                if(x == y)
                    continue;
                x--;
                y--;
                Edges[id].from = x;
                Edges[id].to = y;
                Edges[id++].w = Dist(Point[x],Point[y]);    //建立有向图
            }
            double ans = ZhuLiu(0,N,id);
            if(ans == -1)   //不能构成最小树形图
                printf("poor snoopy
    ");
            else
                printf("%.2lf
    ",ans);
        }
        return 0;
    }

    ~~正在更新

  • 相关阅读:
    [Panzura] identify user operations(copy, open, read ... ) in audit log
    Spark 学习
    Zeppelin 学习
    Delta Lake 学习
    传染病模型 SI
    xcodebuild和xcrun实现自动打包iOS应用程序
    控制UIlabel 垂直方向对齐方式的 方法
    ALAssetsLibrary
    CATransform3D
    AVFoundation的使用
  • 原文地址:https://www.cnblogs.com/zcy19990813/p/9702715.html
Copyright © 2011-2022 走看看