原理就看書吧,看書吧,六度空間的解讀好麻煩啊, 陳越姥姥的講解賽高了。
“六度空間”理論又稱作“六度分隔(Six Degrees of Separation)”理論。這個理論可以通俗地闡述爲:“你和任何一個陌生人之間所間隔的人不會超過六個,也就是說,最多通過五個人你就能夠認識任何一個陌生人。”如圖1所示。
圖1 六度空間示意圖
“六度空間”理論雖然得到廣泛的認同,並且正在得到越來越多的應用。但是數十年來,試圖驗證這個理論始終是許多社會學家努力追求的目標。然而由於歷史的原因,這樣的研究具有太大的侷限性和困難。隨着當代人的聯絡主要依賴於電話、短信、微信以及因特網上即時通信等工具,能夠體現社交網絡關係的一手數據已經逐漸使得“六度空間”理論的驗證成爲可能。
假如給你一個社交網絡圖,請你對每個節點計算符合“六度空間”理論的結點佔結點總數的百分比。
輸入格式:
輸入第1行給出兩個正整數,分別表示社交網絡圖的結點數N(1<N≤104,表示人數)、邊數M(≤33×N,表示社交關係數)。隨後的M行對應M條邊,每行給出一對正整數,分別是該條邊直接連通的兩個結點的編號(節點從1到N編號)。
輸出格式:
對每個結點輸出與該結點距離不超過6的結點數佔結點總數的百分比,精確到小數點後2位。每個結節點輸出一行,格式爲“結點編號:(空格)百分比%”。
輸入樣例:
10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
輸出樣例:
1: 70.00%
2: 80.00%
3: 90.00%
4: 100.00%
5: 100.00%
6: 100.00%
7: 100.00%
8: 90.00%
9: 80.00%
10: 70.00%
代碼如下:
#include<stdio.h>
#include<stdlib.h>
#define ERROR -1 //標記錯誤,表示生成樹不存在
#define MAXSIZE 100
#define MaxVertexNum 100
#define SIX 6
int Visited[MaxVertexNum];
typedef int Vertex;
typedef int WeightType;
typedef char DataType;
typedef struct ENode *PtrToENode;
struct ENode{
Vertex V1, V2; //有向邊
WeightType Weight; //權重
};
typedef PtrToENode Edge;
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex Adjv; //鄰接點下標
WeightType Weight; //邊權重
PtrToAdjVNode Next;
};
typedef struct Vnode{ //頂點表頭節點的定義
PtrToAdjVNode FirstEdge; //邊表頭指針
DataType Data; //存頂針的數據
//注意:很多情況下,頂點無數據,此時Data可以不用出現
}AdjList[MaxVertexNum ]; //AdjList是鄰接表類型
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;//頂點數
int Ne;//邊數
AdjList G;//鄰接表
};
typedef PtrToGNode LGraph;
typedef int Position;
typedef struct QNode *PtrToQNode;
struct QNode{
int *Date;
Position Front, Rear;
int MAXSize;
};
typedef PtrToQNode Queue;
Queue CreateQueue(int MAXSize)
{
Queue Q = (Queue)malloc(sizeof(struct QNode));
Q->Date = (int*)malloc(MAXSize*sizeof(int));
Q->Front = Q->Rear = 0;
Q->MAXSize = MAXSize;
return Q;
}
bool isFull(Queue Q)
{
return ((Q->Rear+1)%Q->MAXSize==Q->Front);
}
bool IsEmpty(Queue Q)
{
return (Q->Front==Q->Rear);
}
int DeleteQ(Queue Q)
{
if(IsEmpty(Q))
{
printf("隊列空");
return ERROR;
}else{
Q->Front = (Q->Front+1)%Q->MAXSize;
//printf("Front = %d ", Q->Front);
//printf("delete = %d\n",Q->Date[Q->Front]);
return Q->Date[Q->Front];
}
}
bool AddQ(Queue Q, int X)
{
if(isFull(Q))
{
printf("隊列滿");
return false;
}
else
{
Q->Rear = (Q->Rear+1)%Q->MAXSize;
Q->Date[Q->Rear] = X;
// printf("Rear = %d ", Q->Rear);
// printf("add = %d \n", Q->Date[Q->Rear]);
return true;
}
}
LGraph CreateGraph(int VertexNum)
{
Vertex V;
//初始化一個 VertexNum 個頂點但沒有邊的圖
LGraph Graph;
Graph = (LGraph)malloc(sizeof(struct GNode));
Graph->Nv = VertexNum;
Graph->Ne = 1;//初始化鄰接表頭指針
for(V=1; V<Graph->Nv; V++)
Graph->G[V].FirstEdge = NULL;
return Graph;
}
void InitializeVisited(int Nv)
{
Vertex V;
for( V=1; V<=Nv; V++ )
{
Visited[V] = false;
// printf("**** = %d \n", V);
}
}
//Visited[]爲全局變量,已經初始化爲false
int SDS_BFS(LGraph Graph, Vertex S) //廣度優先
{
Queue Q;
Vertex V, Last, Tail;
PtrToAdjVNode W;
int Count, Level;
Q = CreateQueue(MAXSIZE);//創建空列隊,MAXSIZE爲外部定義的常數
//訪問頂點S:此處可根據具體訪問需要改寫
//Visit(S);
Visited[S] = true;
Count = 1;
Level = 0;
Last = S;
AddQ(Q, S);//S入隊 第一次只有頭結點入隊
while(!IsEmpty(Q))
{
V = DeleteQ(Q);//彈出結點
// printf(" [%d] ", V);
for(W=Graph->G[V].FirstEdge; W; W = W->Next){ //對圖中的每個頂點W
//若W是V的鄰接點且並未訪問過
if(!Visited[W->Adjv])//若爲被訪問過
//Visit(W);
{
Visited[W->Adjv] = true;
Count++;
Tail=W->Adjv;//當前層尾
AddQ(Q, W->Adjv);//W->Adjv入隊
}
}
if( V==Last ){
Level++;
//printf("%d ", Level);
Last = Tail;
}
if(Level==SIX) break;
}
//DestoryQueue(Q);
return Count;
}
void SIX_Degrees_of_Separation( LGraph Graph )
{
Vertex V;
int Count = 0;
for(V=1; V<=Graph->Nv; V++)
{
InitializeVisited(Graph->Nv);
Count = SDS_BFS(Graph, V);
//printf("\n");
//printf("count = %d ", Count);
printf("%d:", V);
if( V<10 )
printf(" ");
else
printf(" ");
printf("%.2f%%\n", 100.0*(double)Count/(double)Graph->Nv);
}
}
void InsertEdge(LGraph Graph, Edge E)
{
PtrToAdjVNode NewNode;
//插入邊<V1, V2>
//爲V2建立新的鄰接點
NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->Adjv =E->V2;
//將V2插入V1的表頭
NewNode->Next = Graph->G[E->V1].FirstEdge;
Graph->G[E->V1].FirstEdge = NewNode;
//若是-無向圖-還需議案插入<V2, V1>
// 爲V1建立新的鄰接點
NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
NewNode->Adjv = E->V1;
//將V1插入V2的表頭
NewNode->Next = Graph->G[E->V2].FirstEdge;
Graph->G[E->V2].FirstEdge = NewNode;
}
LGraph BuildGraph()
{
LGraph Graph;
Edge E;
Vertex V;
int Nv, i;
scanf("%d", &Nv); //讀入頂點個數
Graph = CreateGraph(Nv);
scanf("%d", &(Graph->Ne)); //讀入邊數
if( Graph->Ne!=0 )
E = (Edge)malloc(sizeof(struct ENode));//建立邊結點
//讀入邊,格式爲“起點,終點, 權重”,插入鄰接矩陣
for( i=0; i<Graph->Ne; i++)
{
scanf("%d %d", &E->V1, &E->V2);
InsertEdge(Graph, E);
}
return Graph;
}
int main()
{
LGraph Graph = BuildGraph();
SIX_Degrees_of_Separation(Graph);
return 0;
}
編譯器:DEV C++