HDU 6386 Age of Moyu [ Dijkstra算法 + 堆优化 ]

4 篇文章 0 订阅
3 篇文章 0 订阅

题目链接:

2018 Multi-University Training Contest 7 Age of Moyu HDU - 6386

题意概括:

给一幅图,N个节点,M条双向边。与以往不同的是并没有给出边权,而给出占有这条边的主人编号。在两条同一个主人的边上切换时不需要花费,而不同主人时需要花费 1 。例如,从 A 主人到 B 主人的边需要花费 1 ,从 B 的边回到 A 的边时,还依然需要花费 1 。要求求出从节点 1 到 N 的最少花费,若到不了,则输出 -1 。

数据范围:

测试数据不超过 20 组

2\leq N\leq 100000  ,  0\leq M\leq 200000

1\leq A_{i},B_{i} \leq N  ,  1\leq C_{i}\leq 1000000

题解分析:

就是单源最短路问题,每条边的权值赋为 1 ,把 Dijkstra算法 改写一下即可。此题和裸的单源最短路唯一区别就是多了一个条件:同一个主人的边之间切换不需要花费。所以,需要改写的地方就是松弛。假如松弛的时候,两条边相邻并且同主,就把cost 设为 0 即可。这里需要维护一个数组,储存原点到其他点的最短路过程中,经过的最后一条边的主人编号。

AC代码:

#include <stdio.h>
#include <queue>
#include <vector>
#include <algorithm>
#include <memory.h>
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;

struct qnode
{
    int v;
    int c;
    qnode(int _v = 0, int _c = 0): v(_v), c(_c) {}
    bool operator < (const qnode &r)const
    {
        return c > r.c;
    }
};

struct Edge
{
    int v, cost,own;
    Edge(int _v = 0, int _cost = 0, int _own = 0): v(_v), cost(_cost),own(_own) {}
};

vector<Edge>E[MAXN];
bool vis[MAXN];
int dist[MAXN];
int own[MAXN];

void Dijkstra(int n, int start) //点的编号从1开始,有n个点
{
    memset(vis, false, sizeof(vis)); //初始化vis
    for (int i = 1; i <= n; i ++) {dist[i] = INF; own[i] = -1;}
    //初始化dist
    priority_queue<qnode>que;
    while (!que.empty())
        que.pop();
    dist[start] = 0;
    que.push(qnode(start, 0));
    qnode tmp;
    while (!que.empty())
    {
        tmp = que.top(); que.pop();
        int u = tmp.v;
        if (vis[u]) continue;
        vis[u] = true;
        for (int i = 0; i < E[u].size(); i ++)
        {
            int v = E[tmp.v][i].v, cost;
            if (own[u] == E[u][i].own)
                cost = 0;
            else
            cost = E[u][i].cost;
            
            if (!vis[v] && dist[v] > dist[u] + cost)
            {
                dist[v] = dist[u] + cost;
                own[v] = E[u][i].own;
                que.push(qnode(v, dist[v]));
            }
        }
    }
}

void addedge(int u, int v, int w,int own)//起点、终点、权重
{
    E[u].push_back(Edge(v, w, own));
}

int main() {
    int N, M;
    while (scanf("%d%d", &N, &M) != EOF) {
        if (M == 0) {printf("-1\n"); continue;}
        for (int i = 0; i <= N; i ++) E[i].clear();  //每次都要初始化vector<Edge>E[MAXN];
        for (int i = 0; i < M; i ++) {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            addedge(b, a, 1, c);
            addedge(a, b, 1, c);
        }
        Dijkstra(N, 1);
        if ( dist[N] == INF)
            printf("-1\n");
        else
        printf("%d\n", dist[N]);
        }
    }

 

                                                       Age of Moyu

                        Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)

Problem Description

Mr.Quin love fishes so much and Mr.Quin’s city has a nautical system,consisiting of N ports and M shipping lines. The ports are numbered 1 to N. Each line is occupied by a Weitian. Each Weitian has an identification number.

The i-th (1≤i≤M) line connects port Ai and Bi (Ai≠Bi) bidirectionally, and occupied by Ci Weitian (At most one line between two ports).

When Mr.Quin only uses lines that are occupied by the same Weitian, the cost is 1 XiangXiangJi. Whenever Mr.Quin changes to a line that is occupied by a different Weitian from the current line, Mr.Quin is charged an additional cost of 1 XiangXiangJi. In a case where Mr.Quin changed from some Weitian A's line to another Weitian's line changes to Weitian A's line again, the additional cost is incurred again.

Mr.Quin is now at port 1 and wants to travel to port N where live many fishes. Find the minimum required XiangXiangJi (If Mr.Quin can’t travel to port N, print −1instead)

Input

There might be multiple test cases, no more than 20. You need to read till the end of input.

For each test case,In the first line, two integers N (2≤N≤100000) and M (0≤M≤200000), representing the number of ports and shipping lines in the city.

In the following m lines, each contain three integers, the first and second representing two ends Ai and Bi of a shipping line (1≤Ai,Bi≤N) and the third representing the identification number Ci (1≤Ci≤1000000) of Weitian who occupies this shipping line.

Output

For each test case output the minimum required cost. If Mr.Quin can’t travel to port N, output −1 instead.

Sample Input

3 3 
1 2 1
1 3 2
2 3 1
2 0
3 2
1 2 1
2 3 2

Sample Output

1
-1
2

Source

2018 Multi-University Training Contest 7

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值