终于AC了“最短路径”

今天做了一道关于最短路径的算法题,虽然最后AC了,但是我写的第一个算法,我认为是没有问题的,自己编写的测试用例也全部通过,反复调试了,都没有错误。可是在OJ上一提交就提示Wrong Answer,真是苦闷啊!希望看到这篇文章的同志们给些提示。

两个算法都是用邻接表存储图的,都是比较纯粹的自定义结构体,使用的是DijkStra算法。虽然用容器也可以实现邻接表,但是个人感觉用结构体是比较简单,可以不用了解底层的实现。但是本人就是喜欢钻研一些基础的东西,无它,兴趣使然。


题目描述:

给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入:

输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
输出:

输出 一行有两个数, 最短距离及其花费。
样例输入:
3 2
1 2 5 6
2 3 4 5
1 3
0 0
样例输出:
9 11


第一个算法---为啥子错撒?

#include <iostream>
#include <malloc.h>
#define MAXVALUE 999999;
#define MAX_VERTEX_NUM 1001
#define MAX_EDGE_NUM 100001
using namespace std;

struct ArcNode{
    int vertex;
    int len;
    int cost;
    ArcNode *nextarc;
};

typedef struct VertexNode{
    ArcNode *firstArc;
    int size;
}VNode[MAX_VERTEX_NUM];

struct Graph{
    VNode nodes;
    int n, e;
};
int dist[MAX_VERTEX_NUM];
int cost[MAX_VERTEX_NUM];
bool visited[MAX_VERTEX_NUM];
//Edge edges[MAX_EDGE_NUM];
void allocateArcNode(ArcNode** arcNode)
{
    *arcNode = (ArcNode*)malloc(sizeof(ArcNode));
    (*arcNode)->nextarc = NULL;
}

void initeGraph(Graph &graph)
{
    for (int i = 1; i <= MAX_VERTEX_NUM; i++)
    {
        graph.nodes[i].firstArc = NULL;
        graph.nodes[i].size = 0;
    }

    graph.n = 0;
    graph.e = 0;
}

void createGraph(Graph &graph, int m)
{
    int v1, v2, len, cost;
    ArcNode* p1 = NULL;
    ArcNode* p2 = NULL;
    for (int i = 1; i <= m; i++)
    {
        allocateArcNode(&p1);
        allocateArcNode(&p2);
        cin >> v1 >> v2 >> len >> cost;
        p1->vertex = v2;
        p1->len = len;
        p1->cost = cost;
        p1->nextarc = graph.nodes[v1].firstArc;
        graph.nodes[v1].firstArc = p1;
        graph.nodes[v1].size++;
        p2->vertex = v1;
        p2->len = len;
        p2->cost = cost;
        p2->nextarc = graph.nodes[v2].firstArc;
        graph.nodes[v2].firstArc = p2;
        graph.nodes[v2].size++;
    }
}

//void printGraph(const Graph& graph, int n)
//{
//  for (int i = 1; i <= n; i++)
//  {
//      ArcNode* arcPtr = graph.nodes[i].firstArc;
//
//      cout << i << ":    ";
//      cout << "size:" << graph.nodes[i].size << endl;
//      while (arcPtr != NULL)
//      {
//          cout << arcPtr->len << ‘ ‘ << arcPtr->cost << ";";
//          arcPtr = arcPtr->nextarc;
//      }
//
//      cout << endl;
//  }
//}

void dijkStra(const Graph &graph, int v0, int n)
{
    int index = v0;
    for (int i = 1; i <= n; i++)
    {
        ArcNode *arcPtr = graph.nodes[index].firstArc;
        while (arcPtr != NULL)
        {
            int tmp = arcPtr->vertex;
            int len = arcPtr->len;
            int co = arcPtr->cost;
            if (visited[tmp] == false || dist[tmp] > dist[index] + len || (dist[tmp] == dist[index] + len && cost[tmp] > cost[index] + co))
            {
                dist[tmp] = arcPtr->len;
                cost[tmp] = arcPtr->cost;
            }
            arcPtr = arcPtr->nextarc;
        }
        int minLen = MAXVALUE;
        int minCost = MAXVALUE;
        for (int j = 1; j <= n; j++)
        {
            if (visited[j] == false && (dist[j] < minLen || (dist[j] == minLen && cost[j] < minCost)))
            {
                minLen = dist[j];
                index = j;
            }
        }
        visited[index] = true;
    }
}

void freeSpaceOfGraph(Graph& graph)
{
    for (int i = 1; i <= graph.n; i++)
    {
        ArcNode *arcPtr = graph.nodes[i].firstArc;
        while (arcPtr != NULL)
        {
            ArcNode *tmp = arcPtr;
            arcPtr = arcPtr->nextarc;
            delete tmp;
        }
    }
}

int main()
{
    int n, m;

    while (cin >> n >> m)
    {
        if (n == 0 && m == 0)
            break;
        int start, end;

        for (int i = 1; i <= n; i++)
        {
            visited[i] = false;
            cost[i] = MAXVALUE;
            dist[i] = MAXVALUE;
        }

        Graph graph;
        initeGraph(graph);
        graph.n = n;
        graph.e = m;
        createGraph(graph, m);
        cin >> start >> end;
        dijkStra(graph, start, n);
        cout << dist[end] << ‘ ‘ << cost[end] << endl;
        freeSpaceOfGraph(graph);
    }
    return 0;
}

第二算法---完美AC

#include <iostream>
#include <malloc.h>
#define MAXVALUE 123123123
#define MAX_VERTEX_NUM 1001
#define MAX_EDGE_NUM 100001
using namespace std;

struct ArcNode{
    int vertex;
    int len;
    int cost;
    ArcNode *nextarc;
};

typedef struct VertexNode{
    ArcNode *firstArc;
    int size;
}VNode[MAX_VERTEX_NUM];

struct Graph{
    VNode nodes;
    int n, e;
};
int dist[MAX_VERTEX_NUM];
int cost[MAX_VERTEX_NUM];
bool visited[MAX_VERTEX_NUM];
//Edge edges[MAX_EDGE_NUM];
void allocateArcNode(ArcNode** arcNode)
{
    *arcNode = (ArcNode*)malloc(sizeof(ArcNode));
    (*arcNode)->nextarc = NULL;
}

void initeGraph(Graph &graph)
{
    for (int i = 1; i <= MAX_VERTEX_NUM; i++)
    {
        graph.nodes[i].firstArc = NULL;
        graph.nodes[i].size = 0;
    }

    graph.n = 0;
    graph.e = 0;
}

void createGraph(Graph &graph, int m)
{
    int v1, v2, len, cost;
    ArcNode* p1 = NULL;
    ArcNode* p2 = NULL;
    for (int i = 1; i <= m; i++)
    {
        allocateArcNode(&p1);
        allocateArcNode(&p2);
        cin >> v1 >> v2 >> len >> cost;
        p1->vertex = v2;
        p1->len = len;
        p1->cost = cost;
        p1->nextarc = graph.nodes[v1].firstArc;
        graph.nodes[v1].firstArc = p1;
        graph.nodes[v1].size++;
        p2->vertex = v1;
        p2->len = len;
        p2->cost = cost;
        p2->nextarc = graph.nodes[v2].firstArc;
        graph.nodes[v2].firstArc = p2;
        graph.nodes[v2].size++;
    }
}

//void printGraph(const Graph& graph, int n)
//{
//  for (int i = 1; i <= n; i++)
//  {
//      ArcNode* arcPtr = graph.nodes[i].firstArc;
//
//      cout << i << ":    ";
//      cout << "size:" << graph.nodes[i].size << endl;
//      while (arcPtr != NULL)
//      {
//          cout << arcPtr->len << ‘ ‘ << arcPtr->cost << ";";
//          arcPtr = arcPtr->nextarc;
//      }
//
//      cout << endl;
//  }
//}

void dijkStra(const Graph &graph, int v0, int n)
{
    int index = v0;
    dist[v0] = 0;
    cost[v0] = 0;
    visited[v0] = true;
    for (int i = 1; i <= n; i++)
    {
        ArcNode *arcPtr = graph.nodes[index].firstArc;
        while (arcPtr != NULL)
        {
            int tmp = arcPtr->vertex;
            int len = arcPtr->len;
            int co = arcPtr->cost;
            if ((visited[tmp] == false) && (dist[tmp] > dist[index] + len
                || (dist[tmp] == dist[index] + len && cost[tmp] > cost[index] + co)))
            {
                dist[tmp] = dist[index] + len;
                cost[tmp] = cost[index] + co;
            }
            arcPtr = arcPtr->nextarc;
        }
        int minLen = MAXVALUE;
        int minCost = MAXVALUE;
        for (int j = 1; j <= n; j++)
        {
            if (visited[j] == true || dist[j] == MAXVALUE)
                continue;
            if (dist[j] < minLen || (dist[j] == minLen && cost[j] < minCost))
            {
                minLen = dist[j];
                minCost = cost[j];
                index = j;
            }
        }
        visited[index] = true;
    }
}

void freeSpaceOfGraph(Graph& graph)
{
    for (int i = 1; i <= graph.n; i++)
    {
        ArcNode *arcPtr = graph.nodes[i].firstArc;
        while (arcPtr != NULL)
        {
            ArcNode *tmp = arcPtr;
            arcPtr = arcPtr->nextarc;
            delete tmp;
        }
    }
}

int main()
{
    int n, m;

    while (cin >> n >> m)
    {
        if (n == 0 && m == 0)
            break;
        int start, end;

        for (int i = 1; i <= n; i++)
        {
            visited[i] = false;
            cost[i] = MAXVALUE;
            dist[i] = MAXVALUE;
        }

        Graph graph;
        initeGraph(graph);
        graph.n = n;
        graph.e = m;
        createGraph(graph, m);
        cin >> start >> end;
        dijkStra(graph, start, n);
        cout << dist[end] << ‘ ‘ << cost[end] << endl;
        freeSpaceOfGraph(graph);
    }
    return 0;
}

/**************************************************************
    Problem: 1008
    User: 凌月明心
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1528 kb
****************************************************************/

时间: 2024-08-27 15:44:18

终于AC了“最短路径”的相关文章

记一个问题的AC

今天突然做一道LCT的染色问题的时候突然想到一个两个月前一道没有AC的题目. 链接 大意是,给一个长度为10^4的序列,最多有255个不同的数字,有最多10^5次方个询问,对于每个询问 l,r 输出[l,r]中不同数字的数目. 记得最初的想法是  用f[i][j],存下数字i的第j次出现位置的下标 ,对每次询问,二分查找,判断每个数字i是否存在在[l,r]内的下标. 时间复杂度是最多是 O((10^5)*255*log(10^4)) ,结果比赛的时候超时了,加了读入优化还是不行. 由于比赛的OJ

树链剖分(以维护线段树为例)

关于树链剖分的有关知识:http://www.cnblogs.com/sagitta/p/5660749.html 以下是洛谷p3384经过无数次WA和RE(最后发现只是有一个函数的调用写反了qwq)终于AC的代码: #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<climits> #in

[转]acm忠告

多做难题 如果你去问那些牛人“这道题你是怎么想到要用XXX方法的”,我估计大部分人都说不出个所以然来.其实很多情况下都是纯凭直觉考虑到的数个思维方向,这种直觉是需要大量的练习来得到的,没有那么多“为什么能想到”,类似于Roba口中的“条件反射题”一样.所以要多做题. 不过这里的“多”不是指数量多,而是质量多.所谓的难题也并不是指要做那种难到天顶的题,而是适合自己的难题.如果一道题能够让你经过数个小时甚至一天的冥思苦想,最后终于AC,我认为这样的题才是最好的.当然这是你要有一些相关基础的前提下才能

【BZOJ 4171】 4171: Rhl的游戏 (高斯消元)

4171: Rhl的游戏 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 74  Solved: 33[Submit][Status][Discuss] Description RHL最近迷上一个小游戏:Flip it.游戏的规则很简单,在一个N*M的格子上,有一些格子是黑色,有一些是白色 .每选择一个格子按一次,格子以及周围边相邻的格子都会翻转颜色(边相邻指至少与该格子有一条公共边的格子 ),黑变白,白变黑.RHL希望把所有格子都变成白色的.不幸

POJ 2349 Arctic Network

Arctic Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18447   Accepted: 5829 Description The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication tec

hdu 1044(bfs+dfs+剪枝)

Collect More Jewels Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6739    Accepted Submission(s): 1564 Problem Description It is written in the Book of The Lady: After the Creation, the cruel

1629 - Cake slicing(DP)

花了近2个小时终于AC,好爽.. 一道类似于最优矩阵链乘的题目,受<切木棍>那道题的启示,该题的原理也是一样的,仅仅只是变成了且面积.那么对应的也要添加维度 . 显然要完整的表示状态,最少要用四维数组.分别表示它的两个对角线顶点的坐标 .   然后横切或者纵切,递归需找更小的矩形,直到矩形内仅仅剩一个樱桃的时候返回0 那么问题就是如何高速的推断一个矩形内有多少个樱桃,于是决定再开一个数组记录这个矩形内樱桃的个数.一開始就是在这个地方超时(开了个五重循环) ,后来想到一个折中的办法,将时间复杂度

POJ1717 Dominoes DP,背包的变形

这道题目比较短,而且有图片很容易懂题意,就是每一张牌,分为上下两部分,上面有几个点,代表上部分为几,下面同样,然后n张牌平行竖直放置,这样每一张牌的上面部分组成第一行,下面部分组成第二行,上下两行的和是有差异的值为gap,每一张牌可以上下反一下,这样可以是的差异值gap缩小,问你使得gap值最小 需要翻牌的最少次数 首先这道题目跟POJ1837有点类似,但是 边界设置这道题明显会麻烦许多,因为之前做过了POJ1837,所以这道题一上来就选择了那个方法,但是a,b值的差异极端为6000,又有负的,

1692: [Usaco2007 Dec]队列变换(BZOJ1640强化版)

1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 682  Solved: 280[Submit][Status] Description FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”.在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席前依次走过. 今年,竞赛委员会在接受队伍报名时,采用了一种新的登记规则:他们把所有队伍中奶牛名字的首