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