现在的位置: 首页 > 综合 > 正文

邻接表(简单模拟)

2018年04月28日 ⁄ 综合 ⁄ 共 1618字 ⁄ 字号 评论关闭

图论(Graph Theory)是数学的一个分支.它以图为研究对象.

图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系.

图论本身是应用数学的一部份.图论起源于著名的哥尼斯堡七桥问题,关于图论的文字记载最早出现在欧拉1736年的著作中,他所考虑的原始问题有很强的实际背景.

图论算法在计算机科学种扮演着很重要的角色,它提供了对很多问题都有效的一种简单而系统的建模方式.很多问题都可以转化为图论问题,然后用图论的基本算法加以解决.

图中最基本的元素是边和点,可以使用点和连接点的边来表示,下面就是一些图的表示.


使用计算机解决图论问题最基本的问题就是如何在程序中存储图.

常用的图的存储方式有邻接矩阵和邻接表.下面分别介绍一下这两种存储结构.

邻接矩阵采用一个矩阵来表示点和点的邻接关系.如果一个图有N个顶点那么用一个N*N的0-1矩阵来表示这个图,如果第i个节点和第j个节点如果有边相连,那么第i行第j个元素就是1,否则为0.这样的方式就需要O(N^2)的存储空间.

当一个图中边很少,但点很多(或者叫稀疏图)的时候,这个邻接矩阵中有大量的0元素,浪费了很大的空间.

邻接表采用的是另外一种思想,直接存储存在的邻接关系.对应每一个顶点,用一个表存放和它邻接的顶点.这样需要的空间就只是O(E),E为图中边的数目.

现在,我们需要把一个图从邻接矩阵表示转换到邻接表表示.

例如,下面表示了从一个图到邻接矩阵和邻接表的转换过程


图:


邻接矩阵:


邻接表:

1: 2 3

2: 1 4 5

3: 1 4

4: 2 3 5

5: 2 4


 

Input

输入数据第1行是一个整数N(N<=500),代表所给是一个有N个顶点的图.

接下来从第2行到第N+1行,给出了1个N*N阶0-1矩阵,第i+1行第j个元素给出了邻接矩阵第i行第j列的元素.同一行的各个元素使用1个空格隔开.

 

Output

输出数据有N行.

第i行格式如下:

i: v1 v2 v3....


v1,v2,v3是和第i个顶点邻接的点的编号,并且v1<v2<v3<....编号之间使用空格隔开,冒号后面有1个空格.第N行末尾有1个换行符.

 

Sample Input

5
0 1 1 0 0
1 0 0 1 1
1 0 0 1 0
0 1 1 0 1
0 1 0 1 0

Sample Output

1: 2 3
2: 1 4 5
3: 1 4
4: 2 3 5
5: 2 4

Hint

输入数据很多,使用scanf,printf避免超时

Source

Author

解题思路:

对于邻接表的深刻理解罢了,没有什么难的,但是要注意不要PE,,用flag变量,边标记边计算是个不错的方法啊。

代码:

#include <cstdio>
#include <string>
#include <iostream>
#include <cstdlib>

using namespace std;

# define MAX 500+4
# define inf 99999999

int edge[MAX][MAX];

int n;

void init()
{
    for ( int i = 1;i <= n;i++ )
    {
        for ( int j = 1;j <= n;j++ )
        {
            if ( i==j )
                edge[i][j] = 0;
            else
                edge[i][j] = inf;
        }
    }
}

void input()
{
    for ( int i = 1;i <= n;i++ )
    {
        for ( int j = 1;j <= n;j++ )
        {
            cin>>edge[i][j];
        }
    }
}


int main(void)
{
    while ( cin>>n )
    {
        init();
        input();
        for ( int i = 1;i <= n;i++ )
        {
            int flag = 0;
            printf ("%d: ",i);
            for ( int j = 1;j <= n;j++ )
             {
                 if ( edge[i][j] )
                 {
                     if ( !flag )
                     {
                         printf("%d",j);
                         flag = 1;
                     }
                     else
                        printf(" %d",j);
                 }

             }
             cout<<endl;
        }
    }


    return 0;
}

抱歉!评论已关闭.