12-B. DS图—图的连通分量

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值