题:风险度量
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;
}