检查网络
给定一个计算机网络以及机器间的双向连线列表,每一条连线与允许两端的计算机进行直接的文件传输,其他计算机间若存在一条连通路径,也可以进行间接的文件传输。
要求实现功能:
任意指定两台计算机,判断整个网络中是否任意两台机器间都可以文件传输?若不可以,请给出当前网络中连通分量的个数及各个连通分量中的机器。 增加两台计算机之间的连线。
基本要求:
至少使用两种结构实现。
数组实现:
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000
using namespace std;
int cc[maxn]; //用来记录每个连通分量中的一个值,cc[1]=3:第一个连通分量中的一个值为3
int par[maxn],ran[maxn],a[maxn],b[maxn];
void Init(int n) //初始化
{
for(int i=0;i<=n;++i){
par[i] = i;
ran[i] = 0;
}
}
int Find_par(int x) //寻找父节点
{
if(par[x]==x) return x;
return par[x] = Find_par(par[x]);
}
void Unite(int x,int y) //可连接的计算机了相连
{
int fx = Find_par(x);
int fy = Find_par(y);
if(fx == fy) return ;
if(ran[fx]<ran[fy])
par[fx] = fy;
else{
par[fy] = fx;
if(ran[fx]==ran[fy])
ran[fx]++;
}
}
int Acount(int n) //计算连通分量个数
{
int cnt=0,flag = 1,k;
for(int i=1;i<=n;++i){
if(Find_par(i)==i){
cnt++;
cc[cnt] = i;
}
}
return cnt;
}
int main()
{
int n,m,ans,mac1,mac2;
char op;
while(n|m){
printf("请输入计算机的数量:");
scanf("%d",&n);
printf("请输入可直接相连的计算机的对数:");
scanf("%d",&m);
if(n>maxn||m>maxn){
printf("\n数据越界,请重新输入!!!\n\n\n");
continue ;
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
Init(n);
printf("请输入可直接相连的计算机机号:\n");
for(int i=1;i<=m;++i){
scanf("%d %d",&a[i],&b[i]);
Unite(a[i],b[i]);
}
while(1){
printf("请输入想要的操作(Q:查询连通情况,A:增加连线 ,N:退出):");
cin>>op;
if(op == 'Q'){ //查询
ans = Acount(n);
if(ans == 1){
printf("任意两台计算机均可连通\n");
}
else{
printf("连通分量的个数为: %d\n",ans);
for(int i=1;i<=ans;i++){
printf("第%d个连通分量中的机器有 : ",i);
for(int j=1;j<=n;++j){
if(Find_par(cc[i])==Find_par(par[j]))
printf("%d ",j);
}
printf("\n");
}
printf("请输入两台计算机序号,判断其二者是都可以连通:(以0,0结束)\n");
while(scanf("%d %d",&mac1,&mac2)){
if(mac1+mac2==0) break;
if(Find_par(mac1) == Find_par(mac2)) printf("%d号计算机与%d号计算机可以连通\n",mac1,mac2);
else printf("二者无法连通\n");
}
}
}
else if(op == 'A'){ //添加连接
int num;
printf("请输入添加的连线数:\n");
scanf("%d",&num);
printf("请输入新添加连线的机器号:\n");
while(num--){
scanf("%d %d",&mac1,&mac2);
Unite(mac1,mac2);
}
continue;
}
else break;
}
printf("\n\n");
}
return 0;
}
/*
10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
输出结果:
任意两台计算机均可连通
10 7
1 2
1 3
1 5
1 9
4 6
4 7
8 10
输出结果:
连通分量的个数为: 3
第1个连通分量中的机器有 : 1 2 3 5 9
第2个连通分量中的机器有 : 4 6 7
第3个连通分量中的机器有 : 8 10
10 5
1 2
1 4
2 6
4 7
3 5
输出结果:
连通分量的个数为: 5
第1个连通分量中的机器有 : 1 2 4 6 7
第2个连通分量中的机器有 : 3 5
第3个连通分量中的机器有 : 8
第4个连通分量中的机器有 : 9
第5个连通分量中的机器有 : 10
10 3
1 10
2 8
8 10
输出结果:
连通分量的个数为: 7
第1个连通分量中的机器有 : 1 2 8 10
第2个连通分量中的机器有 : 3
第3个连通分量中的机器有 : 4
第4个连通分量中的机器有 : 5
第5个连通分量中的机器有 : 6
第6个连通分量中的机器有 : 7
第7个连通分量中的机器有 : 9
10 6
1 2
1 3
3 8
8 10
4 5
6 7
输出结果:
连通分量的个数为: 4
第1个连通分量中的机器有 : 1 2 3 8 10
第2个连通分量中的机器有 : 4 5
第3个连通分量中的机器有 : 6 7
第4个连通分量中的机器有 : 9
*/
结构体实现:
#include <iostream>
#include <cstdio>
#define maxn 1000
using namespace std;
int cc[maxn]; //连通分量
struct node
{
int data;
int ran;
int parent;
}t[maxn];
void Init(int n)
{
for(int i=1;i<=n;++i)
{
t[i].data = i;
t[i].ran = 0;
t[i].parent = i;
}
}
int Find_par(int x)
{
if(t[x].parent==x) return x;
return t[x].parent = Find_par(t[x].parent);
}
void Unite(int x,int y )
{
x=Find_par(x);
y=Find_par(y);
if(x==y) return ;
if( t[x].ran < t[y].ran )
t[x].parent=y;
else{
t[y].parent=x;
if( t[x].ran==t[y].ran)
t[x].ran++;
}
}
int Acount(int n)
{
int cnt=0,flag = 1,k;
for(int i=1;i<=n;++i){
if(t[i].parent == i){
cnt++;
cc[cnt] = i;
}
}
return cnt;
}
int main()
{
int n,m,ans,mac1,mac2;
char op;
while(n|m){
printf("请输入计算机的数量:");
scanf("%d",&n);
printf("请输入可直接相连的计算机的对数:");
scanf("%d",&m);
if(n>maxn||m>maxn){
printf("\n数据越界,请重新输入!!!\n\n\n");
continue ;
}
Init(n);
printf("请输入可直接相连的计算机机号:\n");
for(int i=1;i<=m;++i){
scanf("%d %d",&mac1,&mac2);
Unite(mac1,mac2);
}
while(1){
printf("请输入想要的操作(Q:查询连通情况,A:增加连线 ,N:退出):");
cin>>op;
if(op == 'Q'){ //查询
ans = Acount(n);
if(ans == 1){
printf("任意两台计算机均可连通\n");
}
else{
printf("连通分量的个数为: %d\n",ans);
for(int i=1;i<=ans;i++){
printf("第%d个连通分量中的机器有 : ",i);
for(int j=1;j<=n;++j){
if(Find_par(cc[i])==Find_par(t[j].parent))
printf("%d ",j);
}
printf("\n");
}
printf("请输入两台计算机序号,判断其二者是都可以连通:(以0,0结束)\n");
while(scanf("%d %d",&mac1,&mac2)){
if(mac1+mac2==0) break;
if(Find_par(mac1) == Find_par(mac2)) printf("%d号计算机与%d号计算机可以连通\n",mac1,mac2);
else printf("二者无法连通\n");
}
}
}
else if(op == 'A'){ //添加连接
int num;
printf("请输入添加的连线数:\n");
scanf("%d",&num);
printf("请输入新添加连线的机器号:\n");
while(num--){
scanf("%d %d",&mac1,&mac2);
Unite(mac1,mac2);
}
continue;
}
else break;
}
printf("\n\n");
}
return 0;
}