洛谷P2296 寻找道路

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

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

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

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

(Large extbf{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
", x.dis + 1); return 0; }
			else q.push((Node){u, x.dis + 1});
		}
	}
	printf("-1
");
	return 0;
} 

(largecolor{pink}{byquad Miraclys})

原文地址:https://www.cnblogs.com/Miraclys/p/12268389.html