反向边bfs10pts求调
查看原帖
反向边bfs10pts求调
1377797
KangX楼主2024/10/5 18:04
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int n,m,r[N],d[N],s,t,dis[N];//出度和能到终点的度数
queue<int> q;
vector<int> g[N],g2[N];//g2是反图
bool vis[N],num[N];//num表示这个点符不符合条件,1表示符合条件
void bfs(){
	vis[t]=1;
	q.push(t);
	while(!q.empty()){
		int u=q.front();
		q.pop();
		for(auto v:g2[u]){
			if(!vis[v]){
				vis[v]=1;
				q.push(v);
				d[v]++;
			}
		}
	}
}
int main(){
//	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1,u,v;i<=m;i++){
		cin>>u>>v;
		if(u!=v){
			g[u].push_back(v);
			r[u]++;
			g2[v].push_back(u);
		}
	}
	cin>>s>>t;
	if(s==t){
		cout<<0;
		return 0;
	}
	bfs();
	for(int i=1;i<=n;i++){
		if(r[i]==d[i]) num[i]=1;
	}
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(dis));
	q.push(s);
	vis[s]=1;
	dis[s]=0;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		if(u==t) break;
		for(auto v:g[u]){
			if(!vis[v]&&num[v]){
				vis[v]=1;
				q.push(v);
				dis[v]=dis[u]+1;
			}
		}
	}
	if(dis[t])
		cout<<dis[t];
	else cout<<-1;
	return 0;
}

思路就是通过先跑一边反图确定哪些点能走,再正向跑一遍bfs求最短路。

通过判断一个点的出度和从终点搜过来的点数是否相同来判断当前点能不能走。

2024/10/5 18:04
加载中...