[蓝桥杯][2013年第四届真题]危险系数(暴力+dfs)

题目描述
问题描述
抗日战争时期,冀中平原的地道战曾发挥重要作用。
地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。
我们来定义一个危险系数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)/~

发布了598 篇原创文章 · 获赞 49 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/105219331