HDU 6386 Age of Moyu(BFS+DFS)

2 篇文章 0 订阅

Age of Moyu

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2851    Accepted Submission(s): 876


 

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

 

 

Recommend

chendu   |   We have carefully selected several similar problems for you:  6408 6407 6406 6405 6404 

 

【思路】

每条边染色,连续走相同颜色的边不加代价,换颜色代价加一。可以推断出边是没必要重复走的,因此按照一步能到达的所有点分层次走,总体上BFS,遇到同颜色的接着往下DFS即可。有点卡常数,用链式前向星建图吧。

 

【代码】

//******************************************************************************
// File Name: 1001.cpp
// Author: Shili_Xu
// E-Mail: shili_xu@qq.com
// Created Time: 2018年08月15日 星期三 10时28分59秒
//******************************************************************************

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;

const int MAXN = 1e5 + 5, MAXM = 4e5 + 5, INF = 0x3f3f3f3f;

struct edge {
	int to, color, next;

	edge() {}
	edge(int _to, int _color, int _next) : to(_to), color(_color), next(_next) {}
};

struct node {
	int u, cost;

	node() {}
	node(int _u, int _cost) : u(_u), cost(_cost) {}
};

int n, m, cnt;
edge e[MAXM];
int head[MAXN], dist[MAXN];
bool visited[MAXM];
queue<node> q;

void add_edge(int from, int to, int color)
{
	e[cnt] = edge(to, color, head[from]);
	head[from] = cnt++;
}

void dfs(int u, int c, int d)
{
	dist[u] = min(dist[u], d);
	q.push(node(u, d));
	for (int i = head[u]; i != -1; i = e[i].next) {
		if (visited[i] || e[i].color != c) continue;
		visited[i] = visited[i ^ 1] = true;
		dfs(e[i].to, c, d);
	}
}

int main()
{
	while (scanf("%d %d", &n, &m) == 2) {
		if (m == 0) {
			printf("-1\n");
			continue;
		}
		cnt = 0;
		memset(head, 0xff, sizeof(head));
		for (int i = 1; i <= m; i++) {
			int u, v, c;
			scanf("%d %d %d", &u, &v, &c);
			add_edge(u, v, c);
			add_edge(v, u, c);
		}
		while (!q.empty()) q.pop();
		memset(dist, 0x3f, sizeof(dist));
		memset(visited, false, sizeof(visited));
		dist[0] = 0;
		q.push(node(1, 0));
		while (!q.empty()) {
			node now = q.front(); q.pop();
			for (int i = head[now.u]; i != -1; i = e[i].next) {
				if (visited[i]) continue;
				visited[i] = visited[i ^ 1] = true;
				dfs(e[i].to, e[i].color, now.cost + 1);
			}
			if (dist[n] != INF) break;
		}
		if (dist[n] == INF)
			printf("-1\n");
		else
			printf("%d\n", dist[n]);
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值