题目背景
抗日战争时期,冀中平原的地道战曾发挥重要作用。
题目描述
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数 DF(x,y):
对于两个站点 x 和 y(x=y), 如果能找到一个站点 z,当 z 被敌人破坏后,x 和 y 不连通,那么我们称 z 为关于 x,y 的关键点。相应的,对于任意一对站点 x 和 y,危险系数 DF(x,y) 就表示为这两点之间的关键点个数。
本题的任务是:已知网络结构,求两站点之间的危险系数。
输入格式
输入数据第一行包含 2 个整数 n(2≤n≤1000),m(0≤m≤2000),分别代表站点数,通道数。
接下来 m 行,每行两个整数 u,v(1≤u,v≤n,u=v) 代表一条通道。
最后 1 行,两个数 u,v,代表询问两点之间的危险系数 DF(u,v)。
输出格式
一个整数,如果询问的两点不连通则输出 −1−1。
输入输出样例
输入
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
输出
2
说明/提示
时限 1 秒, 64M。蓝桥杯 2013 年第四届国赛
我们考虑找出所有的路线,如果一个点是关键点,则此点绝对会出现在每一条路线中,故我们在dfs的过程中记录下每个点被走过的次数。最后遍历一遍所有的点,找出和总路径数相同的点就是关键点。
cpp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=4e4+10;
const int N=1e6+10;
int n,m;
vector<int> mp[1001];
int vis[1001];
int cnt[1001];
int sum;
void dfs(int cur,int e)
{
if(cur==e)
{
sum++;
for(int i=1;i<=n;i++)
{
if(vis[i]==1)
cnt[i]++;
}
return ;
}
for(int i=0;i<mp[cur].size();i++)
{
int k=mp[cur][i];
if(!vis[k])
{
vis[k]=1;
dfs(k,e);
vis[k]=0;
}
}
}
void solve()
{
cin>>n>>m;
for(int i=0,x,y;i<m;i++)
{
cin>>x>>y;
mp[x].push_back(y);
mp[y].push_back(x);
}
int s,e;
cin>>s>>e;
vis[s]=1;
dfs(s,e);
int ans=0;
if(sum>0)
{
for(int i=1;i<=n;i++)
{
if(cnt[i]==sum)
ans++;
}
cout<<ans-2<<endl;
}
else
cout<<-1<<endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
ll t=1;
// cin>>t;
while(t--)
{
solve();
}
return 0;
}