鄰接表(簡單模擬)

圖論(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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章