题目描述
问题描述
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数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.
样例输入
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6
样例输出
2
思路:求两个点之间的割点,emmmm一开始想的是求图的割点,但是好像又没多大关系。数据量为1000,我们将每一个点都设置为割点,看能否从u走到v。这样是O(n^2)的时间复杂度,不会超时。网上有大佬用的深搜+回溯,寻找u->v的所有路径,时间复杂度应该差不多。
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxx=2e3+100;
struct edge{
int to,next;
}e[maxx<<1];
int head[maxx<<1],vis[maxx];
int n,m,tot;
int u,v;
inline void init()
{
memset(head,-1,sizeof(head));
tot=0;
}
inline void add(int u,int v)
{
e[tot].next=head[u],e[tot].to=v,head[u]=tot++;
}
inline void dfs(int u)
{
vis[u]=1;
if(u==v) return ;//一个小小的剪枝
for(int i=head[u];i!=-1;i=e[i].next)
{
int to=e[i].to;
if(vis[to]) continue;
dfs(to);
}
}
int main()
{
scanf("%d%d",&n,&m);
init();
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
scanf("%d%d",&u,&v);
int ans=0;
for(int i=1;i<=n;i++)
{
if(i==u||i==v) continue;
for(int j=1;j<=n;j++) vis[j]=0;
vis[i]=1;
dfs(u);
if(vis[v]==0) ans++;
}
printf("%d\n",ans);
return 0;
}
努力加油a啊,(o)/~