Miraclys

一言(ヒトコト)

洛谷P2296 寻找道路

\(\Large\textbf{Description:} \large {在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件:}\)

\(\large {1.路径上的所有点的出边所指向的点都直接或间接与终点连通。}\)

\(\large {2.在满足条件11的情况下使路径最短。}\)

\(\Large\textbf{Solution:} \large {考虑反向建边,然后从终点开始遍历一遍图,把符合条件的点打上标记,再从终点开始跑一边bfs即可。}\)

\(\Large\textbf{Code:}\)

#include <queue>
#include <cstdio>
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int N = 2e5 + 5;
int n, m, cnt, s, t, ans, in[10005], head[10005], vis[1005], f[10005];

struct Edge {
	int to, next;	
}e[N << 1];

struct Node {
	int num, dis;	
};
queue<Node> q;

inline int read() {
	char ch = gc();
	int ans = 0;
	while (ch > '9' || ch < '0') ch = gc();
	while (ch >= '0' && ch <= '9') ans = (ans << 1) + (ans << 3) + ch - '0', ch = gc();
	return ans;	
}

inline void add(int l, int r) {
	e[++cnt].to = r;
	e[cnt].next = head[l];
	head[l] = cnt;	
}

inline void dfs(int now) {
	f[now] = 1;
	for (int i = head[now]; i ; i = e[i].next) {
		int u = e[i].to;
		++vis[u];
		if (f[u]) continue;
		dfs(u);
	}
}

int main() {
	n = read(), m = read();
	int l, r;
	rep(i, 1, m) l = read(), r = read(), add(r, l), ++in[l];
	s = read(), t = read();
	dfs(t);
	rep(i, 1, n) { f[i] = 0; if (in[i] == vis[i]) f[i] = 1; in[i] = 0; }
	q.push((Node){t, 0});
	while (!q.empty()) {
		Node x = q.front();
		q.pop();
		for (int i = head[x.num]; i ; i = e[i].next) {
			int u = e[i].to;
			if (in[u] || !f[u]) continue;
			if (u == s) { printf("%d\n", x.dis + 1); return 0; }
			else q.push((Node){u, x.dis + 1});
		}
	}
	printf("-1\n");
	return 0;
} 

\(\large\color{pink}{by\quad Miraclys}\)

posted @ 2020-02-06 13:27  Miraclys  阅读(76)  评论(0编辑  收藏  举报

关于本博客样式

部分创意和图片借鉴了

BNDong

的博客,在此感谢