4bitにっき

ぽよ

Codeforces Round #333 (Div. 1) A. The Two Routes

問題

Problem - A - Codeforces
頂点数n(n<=400)の無向グラフが与えられる。
各辺は線路が敷かれていることを意味し、電車が移動することが出来る。
また、ある2つの頂点について間に線路が敷かれていない時、その間には道路があり、車が移動できる。
電車も車も頂点1にいる状態から頂点nを目指して同時に出発し、1つの辺を移動するのに1時間がかかる。
ただし、頂点n以外の頂点に留まっていることはできない。
更に、危険なので、電車と車が同じ時刻に同じ頂点にいてはいけない。

電車と車がどちらも頂点nに到着するまでの最小時間を求めよ。


解法

どちらかの乗り物は頂点1から頂点nへの直接的なルートを持っているので、もう片方についてダイクストラ

実装

#define _CRT_SECURE_NO_WARNINGS

#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 400;

struct State
{
	int v, cost;
	State() {}
	State(int _v, int _cost) : v(_v), cost(_cost) {}
	bool operator < (const State &d) const
	{
		return cost > d.cost;
	}
};

int N, M;
vector< vector<int> > e, f;

int Solve(vector< vector<int> > &e)
{
	bool isVisited[MAX_N] = {};
	queue<State> q;
	q.push(State(0, 0));
	while (!q.empty())
	{
		State t = q.front(); q.pop();
		if (isVisited[t.v]) continue;
		isVisited[t.v] = true;
		for (int i = 0; i < e[t.v].size(); i++)
		{
			if (e[t.v][i] == N - 1) return t.cost + 1;
			q.push(State(e[t.v][i], t.cost + 1));
		}
	}
	return -1;
}

signed main()
{
	cin >> N >> M;
	e.resize(N); f.resize(N);
	bool exists[MAX_N][MAX_N] = {};
	for (int i = 0; i < M; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v); u--; v--;
		exists[u][v] = exists[v][u] = true;
		e[u].push_back(v); e[v].push_back(u);
	}
	for (int i = 0; i < N; i++)
	{
		for (int j = i + 1; j < N; j++)
		{
			if (exists[i][j] || exists[j][i]) continue;
			f[i].push_back(j); f[j].push_back(i);
		}
	}
	printf("%d\n", Solve(exists[0][N - 1] ? f : e));
	return 0;
}