月球美容计划之最短路

那HDU的2544作为复习最短路的题目,用不同算法。

迪杰斯特拉

有点像普利姆算法的精简版,不能有负权边

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 99999
#define qmin(a,b) a > b ? b : a

//最短路
//迪杰斯特拉

int G[200][200];
int vis[200];

int djs (int n,int s)
{
    int d[200];
    memset(vis,0,sizeof(vis));
    int i,k;
    for (i = 1;i <= n;i++)
        d[i] = G[1][i];
    d[1] = 0;
    vis[1] = 1;

    int imin,xb = 1;
    for (i = 1;i < n;i++)
    {
        imin = MAX;
        for (k = 1;k <= n;k++)						//以xb为起点↓
            if (!vis[k] && d[xb] + G[xb][k] < d[k])  //最短的那条边,快到碗里来
                d[k] = d[xb] + G[xb][k];

        vis[xb] = 1;

        for (k = 1;k <= n;k++)
            if (!vis[k] && imin > d[k])
                imin = d[xb = k];           //找到最小的点,并以此为起点找最短
        vis[xb] = 1;
    }
    return d[n];
}

int main()
{
    int n,m;

    while (scanf ("%d%d",&n,&m),n || m)
    {
        int i,k;

        for (i = 0;i <= n;i++)
            for (k = 0;k <= n;k++)
                if (i == k)
                    G[i][k] = 0;
                else
                    G[i][k] = MAX;

        for (i = 0;i < m;i++)
        {
            int a,b,c;
            scanf ("%d%d%d",&a,&b,&c);
            if (c < G[a][b])
            {
                G[a][b] = c;
                G[b][a] = c;
            }
        }

        int ans = djs(n,1);

        printf ("%d\n",ans);
    }
    return 0;
}

贝尔曼福特

能够有负权边,就是不停的松弛,时间复杂度有点高

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 99999
#define qmin(a,b) a > b ? b : a

//最短路
//贝尔曼福特

struct E
{
    int e,v;
    int w;
}e[10000];

int cont;

int BF (int n,int s)
{
    int d[200];
    int i,k;
    for (i = 0;i <= n;i++)
        d[i] = MAX;

    d[s] = 0;

    for (i = 1;i < n;i++)     //找n - 1条边
    {
        for (k = 0;k < cont;k++)  //把每条边都遍历一遍
        {
            int a = e[k].e,b = e[k].v;
            d[b] = qmin (d[b],d[a] + e[k].w);  //松弛
        }
    }

    return d[n];
}

int main()
{
    int n,m;

    while (scanf ("%d%d",&n,&m),n || m)
    {
        int i,k;

        cont = 0;
        for (i = 0;i < m;i++)
        {
            int a,b,c;
            int tf = 1;
            scanf ("%d%d%d",&a,&b,&c);

            for (k = 0;k < cont;k++)
                if ((e[k].e == a && e[k].v == b) || (e[k].e == b && e[k].v == a))
                    if (e[k].w > c)
                    {
                        e[k].w = c;
                        tf = 0;
                        break;
                    }

            if (tf)
            {
				//无向图
                e[cont].e = a;
                e[cont].v = b;
                e[cont++].w = c;
                e[cont].e = b;
                e[cont].v = a;
                e[cont++].w=c;
            }
        }

        int ans = BF(n,1);

        printf ("%d\n",ans);
    }
    return 0;
}

弗洛伊德

这简直就像暴力啊,时间复杂度大的夸张,可是求出了每两个点之间的最短路,对于数据多并且图小的题目还是能够考虑的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 99999
#define qmin(a,b) a > b ? b : a

//最短路
//弗洛伊德

int G[200][200];

int fld (int n,int s)
{
    int d[200][200];
    int i,j,k;
    memcpy(d,G,sizeof (G));

    for (i = 0;i <= n;i++)
        for (k = 0;k <= n;k++)
            for (j = 0;j <= n;j++)
                d[k][j] = qmin (d[k][j],d[k][i] + d[i][j]);

    return d[s][n];
}

int main()
{
    int n,m;

    while (scanf ("%d%d",&n,&m),n || m)
    {
        int i,k;

        //邻接矩阵初始化

        for (i = 0;i <= n;i++)
            for (k = 0;k <= n;k++)
                if (i == k)
                    G[i][k] = 0;
                else
                    G[i][k] = MAX;

        for (i = 0;i < m;i++)
        {
            int a,b,c;
            scanf ("%d%d%d",&a,&b,&c);

            if (G[a][b] > c)
            {
                G[a][b] = c;
                G[b][a] = c;
            }
        }

        int ans = fld(n,1);

        printf ("%d\n",ans);
    }
    return 0;
}

SPFA

BF的队列优化,有点像BFS。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 99999
#define qmin(a,b) a > b ? b : a

//最短路
//SPFA

struct node
{
    int v;
    int w;
    struct node *next;
}head[10001];

int q[1000000];   //队列
int s = 0,e = 0;
int SPFA (int n,int st)
{
    bool inq[200];  //标记是否还在队列中(队列中的不在入队列)
    int d[200];
    int i;

    memset (inq,0,sizeof (inq));
    for (i = 0;i <= n;i++)
        d[i] = MAX;
    s = 0;
    e = 0;
    d[st] = 0;
    q[s++] = st;
    inq[st] = 1;    //源点入队列并标记
    while (s > e)
    {
        int now = q[e++];
        inq[now] = 0;  //出队列的就恢复标记

        struct node *p = head[now].next;

        while (p != NULL)
        {
            if(d[p->v] > d[now] + p->w)  //松弛成功
            {
                d[p->v] = d[now] + p->w;

                if (!inq[p->v])         //假设在队列中就不入队列
                {
                    q[s++] = p->v;
                    inq[p->v] = 1;
                }
            }
            p = p->next;
        }
    }
    return d[n];          //其它的和BF一样了
}

int add (int a,int b,int c)    //邻接链表
{
    struct node *t = new node;
    t->v = b;
    t->w = c;
    t->next = NULL;

    struct node *p = &head[a];

    while (p->next != NULL)
        p = p->next;

    p->next = t;

    return 1;
}

int main()
{
    int n,m;

    while (scanf ("%d%d",&n,&m),n || m)
    {
        memset(head,0,sizeof (head));
        int i,k;

        for (i = 0;i < m;i++)
        {
            int a,b,c;
            int tf = 1;
            scanf ("%d%d%d",&a,&b,&c);

            add (a,b,c);
            add (b,a,c);
        }

        int ans = SPFA(n,1);

        printf ("%d\n",ans);
    }
    return 0;
}

http://blog.csdn.net/codehypo

月球美容计划之最短路,布布扣,bubuko.com

时间: 2024-08-25 01:48:53

月球美容计划之最短路的相关文章

月球美容计划之图的储存结构汇总

SJ图论非常流弊,为了省赛队里知识尽量广,我就直接把图continue,如今回想起来丫的全忘了,从头開始吧. 先写写图的存储,再写写最小生成树和最短路的几个经典算法,月球美容计划就能够结束了.0 0.拖了好久,还有非常多内容要写.- - 这次总结了邻接矩阵,邻接表.十字链表.邻接多重表,边集数组,这5种经常使用的图的储存结构,或许能当模板用吧. 邻接矩阵 #include <stdio.h> #include <stdlib.h> #include <string.h>

月球美容计划之最小生成树(MST)

寒假学的两个算法,普里姆,克鲁斯卡尔终于弄明白了,可以发总结了 先说说普里姆,它的本质就是贪心,先从任意一个点开始,找到最短边,然后不断更新更新len数组,然后再选取最短边并标记经过的点,直到所有的点被标记,或者说已经选好了n-1条边. 拿SDUTOJ2144为例,代码如下,可做模板 #include <stdio.h> #include <string.h> #define INF 1000000 //最小生成树 //普里姆 int G[200][200]; int len[20

康复计划之最短路

最短路问题:给你一张图(n个点,m条边),每条边有一个距离.问从一个点到另一个点的最短距离. 最短路主要关注两种算法: Dijkstra  O(n^2) 和 SPFA O(n*m)  (都是最坏复杂度) (其实SPFA几乎无法达到最坏复杂度) Dijkstra: 适用范围(局限性):不存在负权边 思路: 我们取两个集合,一个集合M中为已确定最短距离的点集,另一个集合N为还没有确定最短距离的点集. 我们用集合M中的所有点去更新N中的点的距离,那么集合N中距离最小的点就可以确定该距离为最小距离了.

痴心不改

 2014ACM集训总结 第二次参加ACM集训,可这一次的集训感受大不同以往. 首先这假期学的内容不是那么简单,在学习和刷题的过程中,智商压制现象很严重. 其次,这个假期发生了很多事情,身边的家伙陆续的退役,其实还有我的两个队友. 所以,心中很矛盾,也很复杂,无法用语言表达,只能慢慢调整,让自己恢复正常的感觉. 最后的4场比赛,没有真心的投入,一场中途才赶到实验室,两场提前离场.总的来说,是我逃避现实,我不知道如何面对现实. 一个假期过后,该学会的没有学会,反而留下一堆乱麻,不知道从何捋起.

POJ-2240 -Arbitrage(Bellman)

题目链接:Arbitrage 让这题坑了,精度损失的厉害,用赋值的话,直接全部变成0.00了,无奈下,我只好往里输了,和POJ1860一样找正环,代码也差不多,稍微改改就可以了,但是这个题精度损失的比那个....水过 POJ计划的最短路模块,刷完了,最短路问题,挺坑的,但是就是那点东西,变来变去,就是改改dis[]的更新条件. 明天就要开始POJ的最小生成树了, ME                  TI 704Kb            46Ms #include <iostream> #

刘慈欣作品 吞食者

这是我记忆中读过的第一篇科幻小说,那时我上三四年级,深深的被其中的世界震撼,最后一部分特别的感人,那时候经常去长清清河商厦最中间的一个书店,里边有各种旧书和盗版书,都很便宜,<科幻世界>几块钱一本,从初中就经常去买它,到初三高一那段时间,我已经有五六十本了,当然很不全,里边有三体一二的连载,因为不全所以总是不读,到高中才有机会通读三体三部.前几天才知道吞食者是大刘之作,我的经历告诉我科幻是有用的. [吞食者] (<科幻世界>杂志 2002年11月第11期) 一.波江座晶体 即使距离

KlipC跟随日本Ispace公司探索我们的星球

请让KlipC带你一起,看Ispce如何扩展我们的星球,拓展我们的未来! iSPACE是一家总部位于东京的月球探测公司,其愿景是想扩大人类的生活领域,帮助人类解决登月问题,创造一个可持续发展的世界.Ispace曾计划在2020年向月球轨道发射一次演示任务,并在次年部署探测车进行发射登月. 但Ispace的代表今天(8月22日)宣布,该公司将放弃这次演示,准备在2021年直接将客户有效载荷的固定着陆器发射到月球表面,第二个任务是在2023年部署一个月球车进行表面探测. 调整探测月球时间表的决定主要

CDOJ 1437 谭松松的旅游计划 Label:倍增LCA &amp;&amp; 最短路

谭松松的旅游计划 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 谭松松是一个爱旅游的人,他非常的热爱旅游,即便身体被掏空也要坚持旅游.喵蛤王国由N个城市组成,由N-1条道路连通,每条道路长度为ci,使得任意两座城市都能相互到达.谭松松有M个旅游计划,每个旅游计划有一个起点ai,一个终点bi,所以谭松松想知道,对于每个旅游计划,从起点到终点的最短路长

【图论补完计划】poj 3463 (次短路计数 dijkstra)

Sightseeing Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9127   Accepted: 3206 Description Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the bus moves from one city S to another city F. O