题面
题目背景
抗日战争时期,冀中平原的地道战曾发挥重要作用。
题目描述
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数 :
对于两个站点 和 , 如果能找到一个站点 ,当 被敌人破坏后, 和 不连通,那么我们称 为关于 的关键点。相应的,对于任意一对站点 和 ,危险系数 就表示为这两点之间的关键点个数。
本题的任务是:已知网络结构,求两站点之间的危险系数。
输入格式
输入数据第一行包含 个整数 ,,分别代表站点数,通道数。
接下来 行,每行两个整数 代表一条通道。
最后 行,两个数 ,代表询问两点之间的危险系数 。
输出格式
一个整数,如果询问的两点不连通则输出 。
样例 #1
样例输入 #1
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
样例输出 #1
2
提示
时限 1 秒, 64M。蓝桥杯 2013 年第四届国赛
一句话题意
给定一个无向图,求从起点 到终点 的所有路径上重复的点,若 与 不联通,则输出 。
解题
思路
我们可以使用深度优先搜索(DFS)来计算两个站点之间的危险系数。
具体步骤如下:
-
构建图数据结构。我们可以使用邻接表或邻接矩阵来表示图。邻接表更适合表示稀疏图,而邻接矩阵适合表示稠密图。当然也可以用 动态数组。
-
使用DFS遍历图。从任意一个站点开始,对于每个未访问过的相邻站点,递归调用DFS进行遍历。当到达终点时,我们要累加每个点被遍历的个数。
-
根据询问的两个站点,查找所有 条路径中有重复 次的点就为关键点,并累计个数输出。
vector 的存图与遍历
zxy[v].push_back(u);//存图
zxy[u].push_back(v);
for(int i=0;i<zxy[x].size();i++)
{
if(i==fa)//i 为 x 的父亲节点
continue;
dfs(i);
}
代码实现
#include<bits/stdc++.h>
#define Z return
#define X 0
#define Y ;
using namespace std;
const int N=1010,M=N*2;
int head[N],Next[M],ver[M],tot;//邻接表
void add(int x,int y)
{
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
int n,m,v[N];
int s,e,ans,d[N];
void dfs(int x)
{
if(x==e)//到终点
{
ans++;//总路径数
for(int i=1;i<=n;i++)//累计每个点被遍历的次数
if(v[i]==1)
d[i]++;
return ;
}
v[x]=1;
for(int i=head[x];i;i=Next[i])//邻接表的遍历
{
int y=ver[i];
if(v[y]==1)
continue;
dfs(y);
v[y]=0;//回溯,以遍历下一条路
}
}
int main()
{
scanf("%d%d",&n,&m);//read
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);//存图
}
scanf("%d%d",&s,&e);
dfs(s);
if(ans==0)// u 与 v 不联通
{
puts("-1");
return 0;
}
int sum=0;
for(int i=1;i<=n;i++)//关键点的个数
if(d[i]==ans)
sum++;
printf("%d",sum-1);//多算了起点,所以减一(坑)
Z X Y
}
赞赞赞~