Gym 101149L Right Build[BFS]

2197 ワード

标题:リングがある可能性のあるn+1(<=2 e 5)個の点m(<=2 e 5)の辺の有向図を与えて、点0からaまで、bの総距離が最も短いのはいくらですかを聞きます
構想:私達は先にnから各点までの距離を処理することができて、それからaとbから各点までの距離を処理して、最後に各点を列挙して最小の答えを求めることができて、ここで処理はBFSしか使えなくて、DFSはTLEができて、もう一つのピットは点の記号です(0~n)
コードセクションは次のとおりです.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define ll long long
#define lson l,mid,id<<1
#define rson mid+1,r,id<<1|1

typedef pairpii;
typedef pairpll;

const int MAXN = 200005;
const int MAXM = 1000005;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const double FINF = 1e30;

vectorG[MAXN], RG[MAXN];
int cnt[3][MAXN];
bool vis[MAXN];
struct node
{
	int dep, v;
	node(){}
	node(int _dep,int _v):v(_v),dep(_dep){}
};
void bfs(int ty,int u)
{
	memset(vis, 0, sizeof(vis));
	queueqe;
	qe.push(node(0, u));
	vis[u] = 1;
	while (!qe.empty())
	{
		node now = qe.front(); qe.pop();
		cnt[ty][now.v] = now.dep;
		if (ty == 0)
		{
			for (int i = 0; i < G[now.v].size(); ++i)
			{
				if (vis[G[now.v][i]] == 0) 
				{
					vis[G[now.v][i]] = 1;
					qe.push(node(now.dep + 1, G[now.v][i]));
				}
			}
		}
		else
		{
			for (int i = 0; i < RG[now.v].size(); ++i)
			{
				if (vis[RG[now.v][i]] == 0)
				{
					vis[RG[now.v][i]] = 1;
					qe.push(node(now.dep + 1, RG[now.v][i]));
				}
			}
		}

	}
}
int main()
{
	int n, m, a, b, x, y;
	scanf("%d%d%d%d", &n, &m, &a, &b);
	memset(cnt, INF, sizeof(cnt));
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &x, &y);
		G[x].push_back(y);
		RG[y].push_back(x);
	}
	bfs(0, 0); bfs(1, a); bfs(2, b);
	int ans = INF;
	for (int i = 0; i <= n; ++i)
	{
		if (cnt[0][i] + cnt[1][i] + cnt[2][i] < ans)
		{
			ans = cnt[0][i] + cnt[1][i] + cnt[2][i];
		}
	}
	printf("%d
", ans); }