P8604 [蓝桥杯 2013 国 C] 危险系数 题解
题目
在审完题之后,我们会发现:
怎么枚举呢?我们就将每一个点都设置为
注意事项:
-
队列不要定义在函数里,这是未定义行为。
-
输出
-1 和0 的情况一定要区别(好像没有测试点),-1 是过不去,0 是没有z 。 -
无向图标记走过的边时一定要把回去的路也标上。
代码及解释都在下面了哦。
#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;
}
谢谢观看。