12-图连通与最小生成树-
题目描述
输入无向图顶点信息和边信息,创建图的邻接矩阵存储结构,计算图的连通分量个数。
输入
测试次数t
每组测试数据格式如下:
第一行:顶点数 顶点信息
第二行:边数
第三行开始,每行一条边信息
输出
每组测试数据输出,顶点信息和邻接矩阵信息
输出图的连通分量个数,具体输出格式见样例。
每组输出直接用空行分隔。
输入样例
3
4 A B C D
2
A B
A C
6 V1 V2 V3 V4 V5 V6
5
V1 V2
V1 V3
V2 V4
V5 V6
V3 V5
8 1 2 3 4 5 6 7 8
5
1 2
1 3
5 6
5 7
4 8
输出样例
A B C D
0 1 1 0
1 0 0 0
1 0 0 0
0 0 0 0
2
V1 V2 V3 V4 V5 V6
0 1 1 0 0 0
1 0 0 1 0 0
1 0 0 0 1 0
0 1 0 0 0 0
0 0 1 0 0 1
0 0 0 0 1 0
1
1 2 3 4 5 6 7 8
0 1 1 0 0 0 0 0
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 1 0
0 0 0 0 1 0 0 0
0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0
3
#include<iostream>
using namespace std;
class Map
{
private:
int **mat;//邻接矩阵
int n;
int sum=0;
bool visit[20];
char **vertex;//顶点名字
public:
void set(int num)
{
int i,j;
n=num;
mat=new int *[n];
vertex=new char *[n];
for(i=0;i<n;i++)//初始化
{
vertex[i]=new char[10];
mat[i]=new int[n];
for(j=0;j<n;j++)
mat[i][j]=0;
for(j=0;j<10;j++)
vertex[i][j]=0;
}
for(i=0;i<n;i++)
cin>>vertex[i];
int s;//边数
cin>>s;
while(s--)
{
uinsert();
}
}
int find(char *a)
{
int i,j,flag;
for(i=0;i<n;i++)
{
flag=1;
for(j=0;j<10;j++)
{
if(vertex[i][j]!=a[j])
{
flag=0;
break;
}
}
if(flag==1)
return i;
}
return 0;
}
void uinsert()//无向图
{
char a[10]={0},b[10]={0};
cin>>a>>b;
int x,y;
x=find(a);y=find(b);
mat[x][y]=1;//邻接矩阵图
mat[y][x]=1;
}
void finddfs()
{
int i;
for(i=0;i<n;i++)//初始化
visit[i]=false;
for(i=0;i<n;i++)
{
if(!visit[i])
{
dfs(i);
sum++;
}
}
}
void dfs(int p)//深度搜索
{
int i;
visit[p]=true;//设置已访问
int *a=new int[n];
int pos=0;
for(i=0;i<n;i++)
{
if(mat[p][i])
a[pos++]=i;
}
for(i=0;i<pos;i++)
if(!visit[a[i]])
dfs(a[i]);
delete []a;
}
void print()//输出
{
int i,j;
for(i=0;i<n;i++)//顶点信息
{
if(i==0)
cout<<vertex[i];
else
cout<<" "<<vertex[i];
}
cout<<endl;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(j==n-1)
cout<<mat[i][j];
else
cout<<mat[i][j]<<" ";
}
cout<<endl;
}
cout<<sum<<endl<<endl;
}
};
int main()
{
int t,n;
cin>>t;
while(t--)
{
cin>>n;
Map M;
M.set(n);
M.finddfs();
M.print();
}
return 0;
}