1 条题解

  • 0
    @ 2025-8-24 22:40:37

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar linyukun
    think twice code once

    搬运于2025-08-24 22:40:37,当前版本为作者最后更新于2022-11-12 21:37:11,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目


    在审完题之后,我们会发现:nn10001000 以内,所以一个 O(n2)O(n^2) 的复杂度是可以被接受的。既然这样,就让我们请出老朋友:暴力枚举吧!

    怎么枚举呢?我们就将每一个点都设置为 zz,看能否从 xx 走到 yy。为了防止超时,这里使用时间复杂度更低的 BFS 判断联通,只要搜到了 yy(从 xx),一定有路。搜不到的数量就是答案了。

    注意事项:

    • 队列不要定义在函数里,这是未定义行为。

    • 输出 1-100 的情况一定要区别(好像没有测试点),1-1 是过不去,00 是没有 zz

    • 无向图标记走过的边时一定要把回去的路也标上


    代码及解释都在下面了哦。

    #include<bits/stdc++.h>
    using namespace std;
    bool lu[1005][1005],lu2[1005][1005];//邻接矩阵和临时存储(1有0无边)
    int x,y,n,m,cnt;//cnt计数,其他题面有
    queue<int>ans;
    bool f(int z){//使用BFS来进行判断
    	while(!ans.empty())ans.pop();
    	ans.push(x);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			lu2[i][j]=lu[i][j];//防止原矩阵被破坏
    		}
    	}
    	//ans里的是起点
    	while(!ans.empty()){
    		for(int i=1;i<=n;i++){//然后枚举终点
    			if(lu2[ans.front()][i]==1&&i!=z&&ans.front()!=z){//有路且不含Z
    				if(i==y)return 0;//优化,否则#5TLE
    				ans.push(i);
    				lu2[ans.front()][i]=0;
    				lu2[i][ans.front()]=0;
    			}
    		}
    		ans.pop();
    	}
    	return 1;
    }
    int main(){
    	cin>>n>>m;
    	for(int i=0;i<m;i++){
    		cin>>x>>y;
    		lu[x][y]=1;
    		lu[y][x]=1;//地道是无向的
    	}
    	cin>>x>>y;
    	if(f(0)==1){//不删都到不了的情况
    		cout<<-1;
    		return 0;
    	}
    	for(int z=1;z<=n;z++){//枚举删除点
    		if(z!=x&&z!=y){
    			if(f(z)){
    				cnt++;
    			}
    		}
    	}
    	cout<<cnt;
        return 0;
    }
    

    谢谢观看。

    • 1

    信息

    ID
    5919
    时间
    1000ms
    内存
    128MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者