蓝桥杯_风险度量(一题多解)

题:风险度量
X星系的的防卫体系包含 n 个空间站。这 n 个空间站间有 m 条通信链路,构成通信网。 
两个空间站间可能直接通信,也可能通过其它空间站中转。
对于两个站点x和y (x != y), 如果能找到一个站点z,使得: 
当z被破坏后,x和y无法通信,则称z为关于x,y的关键站点。
显然,对于给定的两个站点,关于它们的关键点的个数越多,通信风险越大。
你的任务是:已知网络结构,求两站点之间的通信风险度,即:它们之间的关键点的个数。
输入数据第一行包含2个整数n(2 <= n <= 1000), m(0 <= m <= 2000),分别代表站点数,链路数。 
空间站的编号从1到n。通信链路用其两端的站点编号表示。 
接下来m行,每行两个整数 u,v (1 <= u, v <= n; u != v)代表一条链路。 
最后1行,两个数u,v,代表被询问通信风险度的两个站点。
输出:一个整数,如果询问的两点不连通则输出-1.
例如: 
用户输入: 
7 6 
1 3 
2 3 
3 4 
3 5 
4 5 
5 6 
1 6 
应该输出: 
2
*/
#include<iostream>
using namespace std;
int pre[1002]={0};//存放每个顶点的前节点 
//寻找x的前节点 
int find(int x)
{	 
	return pre[x] == x ? x : pre[x] = find(pre[x]);
} 
//join将有关的节点进行连接
void join(int x,int y)
{
	//将后一个节点作为前一个节点的根
	pre[find(x)] = find(y);	
} 

int main()
{
	int n;
	int link;
	int u[1002]={0};
	int v[1002]={0};
	int a,b;
	cin>>n>>link; 
	for(int i = 1; i <= n; i++) //初始化站点编号 
	{
		pre[i] = i;
	}
	for(int i = 0; i < link; i++)
	{
		cin>>u[i]>>v[i];
		join(u[i],v[i]);
	}
	cin>>a>>b;
	if(find(a)!=find(b))//说明不连通
	{
		cout<<"-1"<<endl;	
		return 0; 
	} 
	else//说明是连通的 
	{
		int ans = 0;//记录关键节点个数 
		//判断如果与某个点相关联的边都不存在了,是否连通,不联通说明该点为关键点
		//对每个点判断,暴力
		for(int i = 1; i <= n; i++)
		{
			if(i==a || i==b)	continue;
			//将pre数组重置 
			for(int k = 1; k <= n; k++)
			{
				pre[k] = k;
			} 
			for(int j = 0; j < link; j++)
			{
				if(i==u[j] || i==v[j]) continue;
				else
				{
					join(u[j],v[j]);
				}
			}	
			if(find(a)!=find(b))//不联通了 
			{
				ans++;
			}
		} 
		cout<<ans<<endl;
		return 0;
	}
}

解法二:

#include<iostream>
using namespace std;
int link[1002][1002];//连接表 
int count[1002]={0};//每个数字走过的次数 
bool visit[1002];//标记是否走过 
int roads=0;//统计路的个数 
int b;
int n,m;
void dfs(int a)//a是变参 
{
	if(a==b)//连通到最后一个点了 
	{
		roads++;//将路的数目加1 
		for(int i = 1; i <= n; i++)//将所有走过的点的个数加1 
		{
			if(visit[i]==true)
			{
				count[i]++;
			}
		} 
	}
	else//否则继续遍历 
	{
		for(int i = 1; i <= n; i++)
		{
			if(visit[i]==false && link[a][i]==1)
			{
				visit[i] = true;
				dfs(i);
				visit[i] = false;
			}
		}
	}
}
int main()
{
	cin>>n>>m;
	int u,v;
	int num = 0;
	for(int i = 0; i < m; i++)//画出连接表 
	{
		cin>>u>>v; 
		link[u][v] = link[v][u] = 1;
	}
	cin>>u>>b;//输入最后两个数字
	dfs(u); 
	for(int i = 1; i <= n; i++)
	{
		if(count[i] == roads && i!=u && i!=b)
		{
			num++;
		}
	}
	cout<<num<<endl;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

allein_STR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值