【BFS】题目积累

【BFS】题目积累

BFS更适用于扩展性的题目:由几个原始点往外拓展
DFS更适用于遍历性的题目:一条分支走到结束再回头

No Passage

属于题目大意比较难懂的那一类
https://atcoder.jp/contests/abc413/tasks/abc413_f

题目大意

\(n \times m\)的棋盘,若干个目标点
考虑棋盘中每一个位置,统计每一个位置走到任一目标点的最短步数的和
如果走不到,最短步数为0
规定目标点最短步数也为0
有一个特殊规则:先手在每一步都可以封掉一个方向,后手走不了这个方向

思路

每次先手都可以挡住后手的一条路->一个空白点一定要至少能到达2个目标点
->数据范围考虑bfs
把所有目标点(in为2的点)放到队列里 一个点至少要被bfs到2次
->最小距离?
当已经被bfs到2次之后的val值就是最小值

代码

const int N=3010;
int n,m,k;
int in[N][N];
i64 ans[N][N];
void solve(){
    cin>>n>>m>>k;
	queue<array<int,3>> q;
	for(int i=1;i<=k;i++){
		int r,c;
		cin>>r>>c;
		in[r][c]=2;
		q.push({r,c,0});
	}
    while(q.size()){
		auto [x,y,val]=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			int nx=x+dx[i],ny=y+dy[i];
			if(nx<=0 || nx>n || ny<=0 || ny>m) continue;
			if(in[nx][ny]==2) continue;
			in[nx][ny]++;
			if(in[nx][ny]==2){//更新答案
				ans[nx][ny]=(i64)(val+1LL);
				q.push({nx,ny,val+1});
			}
		}
	}
	i64 an=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			an+=ans[i][j];
		}
	}
	cout<<an<<endl;
}

驿站

递增维护:后继和前驱
BFS更新瓶颈结点

https://acm.hdu.edu.cn/contest/problem?cid=1201&pid=1002

题目大意

QQ_1777642378419

思路

QQ_1777642397989

代码

int n,m;
void solve(){
    cin>>n>>m;
    vector<vector<int>> adj(n+1);
    vector<vector<int>> jda(n+1);
    //map<PII,bool> mp;
    for(int i=1;i<=m;i++){
        int u,v;
        cin>>u>>v;
        /*
        if(u==v) continue;
        if(mp[{u,v}]) continue;
        mp[{u,v}]=1;
        */
        adj[u].push_back(v);
        jda[v].push_back(u);
    }
    for(int i=1;i<=n;i++){
        sort(adj[i].begin(),adj[i].end());
    }
    vector<int> ans(n+1,1e9);
    queue<int> q;
    ans[1]=1;
    for(int i=1;i<=n;i++){//从1到n依次解锁:i就是当前最大的
        int minn=1e9;
        //从比他小的转移过来
        for(int j:jda[i]){
            if(j<=i && 1e9>ans[j]){
                minn=whink_min<int>(minn,ans[j]);
            }
        }
        //给初始值:选择之前的更小或者最新的更小
        ans[i]=whink_min<int>(ans[i],whink_max<int>(i,minn));
        //往后找比他小的:比他小的可以被转移
        for(auto son:adj[i]){
            if(son>i) break;
            int t=whink_max<int>(minn,i);
            if(t<ans[son]){
                ans[son]=t;
                q.push(son);
            }
        }
        //BFS往后拓展能走到的没有被走到的小的:i为瓶颈节点
        while(q.size()){
            int u=q.front();
            q.pop();
            for(auto son:adj[u]){
                if(son>i) break;
                if(ans[son]==1e9){
                    ans[son]=i;
                    q.push(son);
                }
            }
        }
    }   
    for(int i=1;i<=n;i++){
        if(ans[i]==1e9) ans[i]=-1;
    }
    for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
    cout<<endl;
}
posted @ 2025-07-06 20:58  White_ink  阅读(23)  评论(0)    收藏  举报