hrbust1339 Touring (Dijkstra最短路径)(邻接表)

本文出自:http://blog.csdn.net/svitter

题意:两个人从c出发,分别想去a,b旅行,两个城市之间只有一条路,有一个相应的价值。求最小的价值。通行的时候只花费一个价值。

本题目的关键在于优先队列,求出a, b, c到各点的最小价值,然后从中挑选一个点作为分开的点。

dijktra算法时用邻接表存储,因为明显是稀疏图。。还有就是存边的时候记得存双向的边,利用优先队列弹出最小的花费。使用邻接表记得初始化node[i] = -1(可以用memset)

AC:

//============================================================================
// Name        : eee.cpp
// Author      : Vit
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;
#define INF 0x1f1f1f1f

struct str
{
    int num;
    int cost;
    str(int n, int c): num(n), cost(c) {}
    str() {}
    friend bool operator < (str s1, str s2)
    {
        return s1.cost > s2.cost;
    }
};

struct Arc
{
    int next_arc;
    int point;
    int cost;
};

Arc arc[20005]; //两个方向的边
int node[5005];
bool flag[5005];

int lowa[5005];
int lowb[5005];
int lowc[5005];

int m, n;

int c, a ,b;

void dijkstra(int src, int n, int *low)//low表示到每个点的最短距离
{
    memset(flag, 0, sizeof(flag));

    priority_queue <str> q;
    q.push(str(src, 0));
    int kk = 0;
    while(kk < n && !q.empty())
    {
        str s = q.top();
        q.pop();
        if(flag[s.num])
            continue;
        flag[s.num] = 1;
        low[s.num] = s.cost;
        kk++;
        for(int e = node[s.num]; e != -1; e=arc[e].next_arc)
        {
            if(!flag[arc[e].point])
            {
                q.push(str(arc[e].point, arc[e].cost + s.cost));
            }
        }
    }
}

void ace()
{
    //work point
    int i, no = 1;
    int u, v, w;
    while(~scanf("%d%d", &n, &m))
    {
        memset(node, -1, sizeof(node));

        memset(lowa, 0x1f, sizeof(lowa));
        memset(lowb, 0x1f, sizeof(lowb));
        memset(lowc, 0x1f, sizeof(lowc));
        scanf("%d%d%d", &a, &b, &c);
        for(i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);

            //头插法建立邻接表
            arc[i].next_arc = node[u];
            arc[i].point = v;
            arc[i].cost = w;
            node[u] = i;

            //反向边(本身无序)
            arc[m + i].next_arc = node[v];
            arc[m + i].point = u;
            arc[m + i].cost = w;
            node[v] = m + i;
        }

        dijkstra(a, n, lowa);
        dijkstra(b, n, lowb);
        dijkstra(c, n, lowc);

        printf("Scenario #%d\n", no++);
        int res = INF;
        int sum;
        for(i = 1; i <= n; i++)//在i处分开
        {
            sum = lowa[i] + lowb[i] + lowc[i];
            if(sum < res)
                res = sum;
        }

        if(res >= INF)
        {
            printf("Can not reah!\n\n");
        }
        else
        {
            printf("%d\n\n", res);
        }
    }
}

int main()
{
    ace();
    return 0;
}
时间: 2024-09-30 06:32:48

hrbust1339 Touring (Dijkstra最短路径)(邻接表)的相关文章

ACM:最短路,dijkstra,邻接表的建立,使用邻接表跟优先队列的dijkstra,Bellman-Ford,Floyd。。

(一)dijkstra,邻接矩阵 所有边权均为正,不管有没有环,求单个源点出发,到所有节点的最短路.该方法同时适用于有向图和无向图. #include <iostream> #include <string> #include <stack> using namespace std; const int MAXN = 1000; const int INF = 100000000; int n, m; int maze[MAXN][MAXN], vis[MAXN], d

【HDU 1874 2544 2066 2112】 Dijkstra单源最短路径专题 —— 优先队列+邻接表/邻接矩阵

HDU 1874  畅通工程续 解题报告: 由于顶点(城镇)的数目只有200个,所以可以采用邻接矩阵的形式来存储,代码会更简洁些,也不容易出错.但是处于练习的目的,采用邻接表+优先队列的方式实现,优先队列使用STL中的priority_queue.很基础的单源单汇最短路径. HDU 2544  最短路 解题报告: 基本和1874是一样的,只是数据量小了,并且要求当n==0 && m==0时终止,值得注意!这道题同时也保证了一定是可达的,所以输出时可以直接输出. HDU 2066  一个人的

hrbust 1339 Touring 最短路Dijkstra 邻接表

题目描述: 两个人从同一出发点去不同的地方,路的距离会造成花费的多少,所以两个人走的越短越好,并且两个人同乘一辆车可以使花费更低,给出每条路所连接的两个城市及该线路的花费以及两个人的出发点和他们各自的目的地,求他们需要的最小花费是多少 分析: 先同乘一段距离,再分开走,形走路线是一个Y形路线,找出一个点,使他到出发点以及他们各自的目的地三个地方的最短距离的和最小,这三个距离的和就是他们所需的最小距花费 这道题换了三种方法打的,第一种是邻接矩阵 乱入 优先队列,超空间,w[i][j]来储存 i 地

邻接表实现Dijkstra算法以及DFS与BFS算法

//============================================================================ // Name : ListDijkstra.cpp // Author : fffff // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //==========================

最短路径(四)—Bellman-Ford的队列优化(邻接表)

上一节我们写了Bellman-Ford算法解决负权边的问题: 邻接表存储图: n个顶点,m条边. 数组实现邻接表.对每一条边进行1-m编号.用u,v,w三个数组来记录每条边的信息,即u[i],v[i],w[i]表示第i条边是从第 u[i]号顶点到v[i]号顶点且权值为w[i]. first数组的1-n号单元格分别用来存储1-n号顶点的第一条边的编号,初始的时候因为没有边加入所有都是-1.即first[u[i]]保存顶点u[i]的第一条边的编号,next[i]存储"编号为i的边"的&qu

POJ 2387 Til the Cows Come Home dijkstra算法 用邻接表和邻接矩阵

题目如下: Til the Cows Come Home Time Limit: 1000MS        Memory Limit: 65536K Total Submissions: 27726        Accepted: 9353 Description Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wa

POJ3159 Dijkstra+邻接表+优先队列

今天学习到了一种新姿势,用邻接表+优先队列优化Dijkstra,这样时间复杂度就由O(N^2+E)变为O(NlogN+E),妈妈再也不用担心我超时了!~\(^o^)/ Candies Time Limit: 1500MS   Memory Limit: 131072K Total Submissions: 25077   Accepted: 6810 Description During the kindergarten days, flymouse was the monitor of his

Dijkstra[两种邻接表+优先队列优化]

Dijksta算法中,如果我们采用的是邻接矩阵来存的,第一点浪费的空间比较多,第二点我们知道算法的时间复杂度在O(n*n),这样的算法可以说并不是很好,所以我们考虑优化它首先我们可以优化存储结构,采用邻接表来存储,其次我们可以用优先队列来排序大小,其时间复杂度大大降低. 需要注意的是pair是按照第一个元素的大小排序,如果相同才按照第二个,所以我们要把d[i]包装在第一个元素上. vector实现邻接表+优先队列 (假设边一开始是字符型的,这么假设是为了加点难度) #include<iostre

The Postal Worker Rings Once(UVA 117)最短路径—SPFA算法+邻接表

The Postal Worker Rings Once From:UVA, 117 Time Limit: 3000 MS Background Graph algorithms form a very important part of computer science and have a lineage that goes back at least to Euler and the famous Seven Bridges of K?nigsberg problem. Many opt