`
huyifan951124
  • 浏览: 83228 次
社区版块
存档分类
最新评论

最小生成树专题

 
阅读更多

poj2421,poj2560,poj1789

这些都是一些比较基础的最小生成树的题目,在这里我分别用两种方法来实现--kruskal以及prim(其中prim是建哥写的,kruskal是我写的).

//poj2421 kruskal
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int n,m;
int a[105][105],d;
int p[105],xa,yb;
int sum,res;
typedef struct Node
{
    int value;
    int l;
    int r;
};
Node edges[105*105];
int find_set(int x)
{
    if(x!=p[x])
        p[x]=find_set(p[x]);
    return p[x];
}
bool cmp(Node e1,Node e2)
{
    return e1.value<e2.value;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        p[i]=i;
    }
    int sym=0,mm=0,m=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&d);
            a[i][j]=a[j][i]=d;

        }
    }
    scanf("%d",&mm);
    for(int i=0;i<mm;i++)
    {
        scanf("%d%d",&xa,&yb);
        a[xa][yb]=0;

    }
    for(int i=1;i<n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            edges[m].l=i;
            edges[m].r=j;
            edges[m].value=a[i][j];
            m++;
        }
    }
    sort(edges,edges+m,cmp);
    for(int i=0;i<m;i++)
    {
        int fx=find_set(edges[i].l);
        int fy=find_set(edges[i].r);
        if(fx!=fy)
        {
            sum+=edges[i].value;
            p[fy]=fx;
        }

    }
    printf("%d\n",sum);

  return 0;
}

//poj2421 prim
#include <stdio.h>
#include <string.h>

#define INF 0x3f3f3f3f

int maps[305][305];
bool vis[305];
int dis[305];
int n;

int Prim()
{
    memset(vis,false,sizeof(vis));
    for(int i=1; i<=n; i++)
        dis[i] = INF;
    int ans=0;
    dis[1] = 0;
    for(int i=1; i<=n; i++)
    {
        int tmp = INF,k=0;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j]&&dis[j]<tmp)
            {
                tmp = dis[j];
                k=j;
            }
        }

        vis[k] = true;
        ans+=tmp;
        for(int i=1; i<=n; i++)
        {
            if(!vis[i]&&dis[i]>maps[k][i])
                dis[i] = maps[k][i];
        }
    }
    return ans;
}

int main()
{
    while(scanf("%d",&n),n)
    {
        for(int i=0; i<=n; i++)
        {
            for(int j=0; j<=n; j++)
                if(i==j)
                    maps[i][j]=0;
                else maps[i][j] = INF;
        }
        for(int i=0; i<n-1; i++)
        {
            int t;
            char a[2],b[2];
            scanf("%s%d",a,&t);
            for(int j=0; j<t; j++)
            {
                int dist;
                scanf("%s%d",b,&dist);
                maps[a[0]-'A'+1][b[0]-'A'+1] = maps[b[0]-'A'+1][a[0]-'A'+1] = dist;
            }
        }
        printf("%d\n",Prim());
    }
    return 0;
}

//poj2560 kruskal

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int t;
typedef struct Node
{
    double x;
    double y;
};
typedef struct Edge
{
    int l;
    int r;
    double value;
};
Edge edges[105*105];
Node node[105];
int p[105],n;
double sum;
bool cmp(Edge e1,Edge e2)
{
    return e1.value<e2.value;
}
int find_set(int x)
{
    if(x!=p[x])
        p[x]=find_set(p[x]);
    return p[x];
}
int main()
{
    sum=0;
    scanf("%d",&n);

    for(int i=1;i<=n;i++)
    {
        scanf("%lf%lf",&node[i].x,&node[i].y);
        p[i]=i;
    }
    int m=0;
   for(int i=1;i<=n;i++)
   {
       for(int j=1;j<=n;j++)
       {
            double d=sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y));
            edges[m].l=i;
            edges[m].r=j;
            edges[m++].value=d;
       }
   }

    sort(edges,edges+m,cmp);

   /* for(int i=0;i<m;i++)
    {
        printf("%lf\n",edges[i].value);
    }*/

    for(int i=0;i<m;i++)
    {
        int fx=find_set(edges[i].l);
        int fy=find_set(edges[i].r);
        if(fx!=fy)
        {
            sum+=edges[i].value;
            p[fy]=fx;
        }
    }
    printf("%.2lf\n",sum);
    return 0;
}

//poj 2560 prim
#include <stdio.h>
#include <string.h>
#include <math.h>

#define INF 0x3f3f3f3f

int n;
double maps[300][300];
bool vis[300];
double dis[300];

struct Point {
    double x;
    double y;
}points[300];

double Prim()
{
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;i++)
        dis[i] = INF;

    dis[1] = 0;
    double ans =0;
    for(int i=1;i<=n;i++)
    {
        double tmp = INF;
        int k =0;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<tmp)
            {
                tmp = dis[j];
                k= j;
            }
        }

        vis[k]=true;
        ans+=tmp;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&dis[i]>maps[k][i])
                dis[i] = maps[k][i];
        }
    }
    return ans;
}

int main()
{

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&points[i].x,&points[i].y);

    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            double x = points[i].x - points[j].x;
            double y = points[i].y - points[j].y;
            maps[i][j] = sqrt(x*x+y*y);
        }
    }
    printf("%.2lf\n",Prim());

    return 0;
}

//poj1789 kruskal

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
char str[2050][10];
int p[2050];
typedef struct Edge
{
  int l;
  int r;
  int value;
};
bool cmp(Edge e1,Edge e2)
{
    return e1.value<e2.value;
}
int find_set(int x)
{
    if(x!=p[x])
        p[x]=find_set(p[x]);
    return p[x];
}
Edge edges[2050*2050];
int getDif(int x,int y)
{
    int num=0;
    for(int i=0;i<7;i++)
    {
        if(str[x][i]!=str[y][i])
        {
            num++;
        }
    }
    return num;
}
int main()
{

    while(scanf("%d",&n)&&n!=0)
    {
        memset(edges,0,sizeof(edges));
        memset(str,0,sizeof(str));
        int m=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str[i]);
            p[i]=i;
        }

        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                int num=getDif(i,j);
                edges[m].l=i;
                edges[m].r=j;
                edges[m++].value=num;
            }
        }
        sort(edges,edges+m,cmp);
        int sum=0;
        for(int i=0;i<m;i++)
        {
            int fx=find_set(edges[i].l);
            int fy=find_set(edges[i].r);
            if(fx!=fy)
            {
                sum+=edges[i].value;
                p[fy]=fx;
            }
        }
        printf("The highest possible quality is 1/%d.\n",sum);

    }

return 0;

}

//poj1789 prim
#include <stdio.h>
#include <string.h>

#define INF 0x3f3f3f3f

int maps[2005][2005];
char str[2005][2005];
int dis[2005];
bool vis[2005];
int n;

int Prim()
{
    memset(vis,false,sizeof(vis));
    for(int i=1; i<=n; i++)
        dis[i] = INF;
    int ans=0;
    dis[1] = 0;
    for(int i=1; i<=n; i++)
    {
        int tmp = INF,k=0;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j]&&dis[j]<tmp)
            {
                tmp = dis[j];
                k=j;
            }
        }

        vis[k] = true;
        ans+=tmp;
        for(int i=1; i<=n; i++)
        {
            if(!vis[i]&&dis[i]>maps[k][i])
                dis[i] = maps[k][i];
        }
    }
    return ans;
}

int main()
{
    while(scanf("%d",&n),n)
    {
        for(int i=0;i<n;i++)
            scanf("%s",str[i]);

        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                int dist = 0;
                for(int k=0;k<7;k++)
                {
                    if(str[i][k]!=str[j][k])
                        dist++;
                }
                maps[i+1][j+1] = dist;
            }
        }
        printf("The highest possible quality is 1/%d.\n",Prim());
    }
    return 0;
}

 

分享到:
评论

相关推荐

    [宫水三叶的刷题日记]:(图论)最小生成树1

    《宫水三叶的刷题日记》系列主要探讨的是图论中的一个重要概念——最小生成树。最小生成树问题是在加权无向图中找到一棵包括所有顶点的树,使得树的所有边的权重之和尽可能小。在这个专题中,作者通过一系列的题目,...

    图论专题之生成树_唐文斌.ppt

    Borůvka's算法是另一种求解最小生成树的方法,它每次选择每个连通块到其他连通块的最小边,逐步合并连通块,最坏情况下需要进行logn次合并,时间复杂度为O((m+n)logn),在随机图中可达到O(n+m)。 除了最小生成树,...

    数学建模 图论 课件 最小生成树 广度和深度搜索

    华中农业大学数学建模基地提供的课件涵盖了图论的基础概念,如顶点、边、度数、完全图等,以及图论在实际问题中的应用,如最短路径、最小生成树、二部图匹配和网络流等问题的求解方法。通过学习这些内容,可以提升...

    生成树专题

    关于生成树算法的拓展和深入讲解,除了最基础的生成树算法外还讲解了多路增广、最小瓶颈生成树等问题

    北京大学ACM暑期课课件

    7.15 若干图论问题:最小生成树 最短路 强连通分量、桥和割点 等 7.16 网络流算法:基本的网络流算法,Dinic算法,带上下界的网络流,最小费用流 7.17 数学题:组合数学,数论等 7.18 最小生成树和动态规划

    数学建模图论模型专题

    数学建模图论模型专题 最短路问题及算法 最小生成树及算法 旅行售货员问题

    图论算法合计

    本文将深入探讨图论算法的一些核心概念,包括最短路径算法、最小生成树、次小生成树以及并查集,并结合提供的文件名称,分析它们在实际问题中的应用。 首先,我们来看最短路径算法。Dijkstra算法和Floyd-Warshall...

    上海交通大学ACM算法模板

    1. 最小生成树(Kruscal算法) 2. 最小生成树(Prim算法) 3. 单源最短路径(Bellman-ford算法) 4. 单源最短路径(Dijkstra算法) 5. 全源最短路径(Folyd算法) 6. 拓扑排序 7. 网络预流和最大流 8. 网络最小费用最大流 9. ...

    北京大学2011年acm暑期培训课件

    5) 若干图论问题:最小生成树 强连通分量、桥和割点等 6) 计算几何:线与线求交,线与面求交,求凸包,半平面求交等 7) 网络流算法:基本的网络流算法,Dinic算法,带上下界的网络流,最小费用流 8) 数学题:组合...

    php-leetcode题解之连接所有点的最小费用.zip

    这个问题的一个常见解决方案是使用Prim或Kruskal算法,这两种都是经典的图算法,用于寻找连通图的最小生成树。 1. **Prim算法**:这是一种贪心算法,从一个起始节点开始,每次添加一条使得当前生成树与未加入树的...

    头歌存储系统(HUST) 全部七关代码

    《头歌存储系统(HUST) 全部七关代码》是针对计算机存储体系的一系列实践练习,旨在帮助学习者深入理解存储系统的运作原理。在这个过程中,我们将通过七个不同的关卡,逐步探索从汉字字库到不同缓存组织结构的设计...

    ACM 算法模板集

    1. 最小生成树(Kruscal算法) 2. 最小生成树(Prim算法) 3. 单源最短路径(Bellman-ford算法) 4. 单源最短路径(Dijkstra算法) 5. 全源最短路径(Folyd算法) 6. 拓扑排序 7. 网络预流和最大流 8. 网络最小费用最大流 9. ...

    天津大学考研面试算法专题(很全面)

    这类问题包括霍夫曼编码、Prim最小生成树算法、Kruskal最小生成树算法等。 6. **回溯法**:当面临多种选择时,通过试探所有可能的解决方案并逐一排除不合适的,直到找到正确答案。如八皇后问题、数独问题等。 7. *...

    软件设计师专题10算法分析

    2. 分类:包括排序算法(如冒泡排序、快速排序、归并排序)、搜索算法(如二分查找、广度优先搜索、深度优先搜索)、图论算法(如最短路径算法、最小生成树算法)等。 二、时间复杂度与空间复杂度 1. 时间复杂度:...

    几何计算专题训练题目(For Acm)

    这两种算法都是贪心策略,Kruskal's Algorithm 是基于边的最小生成树,而 Prim's Algorithm 是基于节点的最小生成树。 5. **土二划分** - 这是一个多边形分割问题,目标是统计具有相同边数的区域。首先,需要构建...

    NOIP 2019 提高班专题集训课件.zip

    《济南提高组突破营图论.pptx》将可能涵盖图的基本概念,如树、最短路径、最小生成树、拓扑排序等,并通过实例解析它们在信息学竞赛中的应用。 数据结构是算法的基础,高效的存储和访问数据是解决问题的关键。...

    数据结构专题-清华大学NOI2016金牌讲座

    3. **图数据结构**:图的表示(邻接矩阵和邻接表),图的遍历(深度优先搜索和广度优先搜索),最小生成树(Prim算法、Kruskal算法)和最短路径问题(Dijkstra算法、Floyd算法)。 4. **动态规划和贪心策略**:在...

    大一暑假专题练习ac代码

    4. **图论算法**:Dijkstra最短路径算法、Floyd-Warshall所有顶点对最短路径、Prim最小生成树、Kruskal最小生成树、拓扑排序、二分图匹配等,这些在处理网络问题、社交网络分析等方面非常有用。 5. **动态规划**:...

    HDU 专题分类(2013年8月)

    - **算法应用**:最小生成树算法如Prim或Kruskal,用于构建连接所有节点的最低成本路径。 #### 4. MinimumTransportCost (最低运输成本) - **问题描述**:涉及物流规划,寻找运输物品的最低成本路线。 - **算法应用...

Global site tag (gtag.js) - Google Analytics