PAT:06-圖3 六度空間

06-圖3 六度空間

“六度空間”理論又稱作“六度分隔(Six Degrees of Separation)”理論。這個理論可以通俗地闡述爲:“你和任何一個陌生人之間所間隔的人不會超過六個,也就是說,最多通過五個人你就能夠認識任何一個陌生人。”如圖1所示。
六度空間“六度空間”理論雖然得到廣泛的認同,並且正在得到越來越多的應用。但是數十年來,試圖驗證這個理論始終是許多社會學家努力追求的目標。然而由於歷史的原因,這樣的研究具有太大的侷限性和困難。隨着當代人的聯絡主要依賴於電話、短信、微信以及因特網上即時通信等工具,能夠體現社交網絡關係的一手數據已經逐漸使得“六度空間”理論的驗證成爲可能。

假如給你一個社交網絡圖,請你對每個節點計算符合“六度空間”理論的結點佔結點總數的百分比。
輸入格式:

輸入第1行給出兩個正整數,分別表示社交網絡圖的結點數N(1<N≤10​3​​,表示人數)、邊數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%

需要記錄每一個點對應臨界點的尾部頂點,隊列操作的頂點==尾部頂點就表示該點的所有臨界點已經遍歷完了或者當空間層數已經大於6時需要跳出循環

#include<iostream>
#include <iomanip>
#include<cstdio>
#include<cmath>
#include <queue>

using namespace std;
/*
  圖的鄰接矩陣表示
*/

/*最多的結點數是100*/
#define MAXVertextNum 100 
/*雙字節無符號整數的最大值65535,即無窮大*/
#define INFINIIY 65535
typedef int Vertex;//用下標表示頂點
typedef int WeightType;//邊的值表示權重
typedef int DataType;//頂點數據



/* 邊的定義*/
typedef struct ENode *PtrToENode;
struct ENode{
	//有向邊<V1,V2>
	Vertex V1,V2;
	//權重
	WeightType Weight;
};
typedef PtrToENode Edge;

/*鄰接點定義*/
typedef struct AdjNode *ptrToAdjNode;
struct AdjNode{
	//下標
	Vertex AdjV;
	//權重
	WeightType Weight;
	//指向連接點的指針
	ptrToAdjNode Next;
};

/*鄰接表的定義*/
typedef struct Vnode{
	//邊表的頭指針
	ptrToAdjNode firstEdge;
	//存頂點的數據,不需要下標了,該結構體數組的索引就是頂點的下標
	DataType data;
}AdjList[MAXVertextNum];/*Adj爲鄰接表*/

/*圖的定義*/
typedef struct GNode *ptrToGNode;
struct GNode{
	//頂點數
	int Nv;
	//邊數
	int Ne;
	//鄰接表
	AdjList G;
};
typedef ptrToGNode LGraph;

void Visit( Vertex V);

void DFS(LGraph Graph,Vertex V);

LGraph CreateGraph( int VertexNum );

void InsertEdge( LGraph Graph, Edge E );

LGraph BuildGraph();
int BFS(LGraph Graph,Vertex V);

int main(){
	LGraph Graph = BuildGraph();
	for(Vertex V = 0;V<Graph->Nv;V++){
		int count = BFS(Graph , V);
		cout<< V + 1 << ": " <<setiosflags(ios::fixed)<<setprecision(2)<<((double)(count)/Graph->Nv) * 100 << "%" <<endl;
	}
	
	return 0;
}

//初始化一個圖
LGraph CreateGraph( int VertexNum ){
	LGraph Graph = new GNode;
	Graph->Nv = VertexNum;
	Graph->Ne = 0;
	//將所有結點的頭指針置空
	for(Vertex V = 0 ; V < Graph->Nv ; V++){
		Graph->G[V].firstEdge = NULL;
	}
	
	return Graph;
}
void InsertEdge( LGraph Graph, Edge E ){
	E->V1 = E->V1 - 1;
	E->V2 = E->V2 - 1;
	//將V2插入V1的鏈表中,從頭頭指針插入
	ptrToAdjNode node = new AdjNode;
	node->AdjV = E->V2;
	node->Weight = E->Weight;
	node->Next = Graph->G[E->V1].firstEdge;
	Graph->G[E->V1].firstEdge = node;

	ptrToAdjNode rnode = new AdjNode;
	//無向圖還需要把V1插入到V2上
	rnode->AdjV = E->V1;
	rnode->Weight = E->Weight;
	rnode->Next = Graph->G[E->V2].firstEdge;
	Graph->G[E->V2].firstEdge = rnode;
}
LGraph BuildGraph(){
	Vertex VertexNum;
	Edge E;
	//初始化圖
	cin >> VertexNum;
	LGraph Graph = CreateGraph(VertexNum);
	cin >> Graph->Ne;
	if(Graph->Ne != 0){
		E = new ENode;
		
		for(int i = 0 ; i < Graph->Ne ; i++){
			cin >> E->V1 >> E->V2;
			InsertEdge(Graph,E);
		}
	}
	
	return Graph;
}


int BFS(LGraph Graph,Vertex V ){
	if(V > Graph->Nv){
		return 0;
	}
	bool Visted[MAXVertextNum] = {false};
	/* 以V爲出發點對Graph進行BFS搜索 */
	queue<Vertex> Q; 
	int count = 1;
	Vertex foot;
	int level = 0;
	foot = V;
	Vertex tail = V;
	Visted[V] = true;
	Q.push(V);
	while(!Q.empty()){
		V = Q.front();
		Q.pop();
		for(ptrToAdjNode cur = Graph->G[V].firstEdge ; cur ; cur = cur->Next){
			if(!Visted[cur->AdjV]){
				Visted[cur->AdjV] = true;
				Q.push(cur->AdjV);
				count ++;
				tail = cur->AdjV;
			}
		}
		if(foot == V){
			level ++;
			foot = tail;
		}
		if(level == 6){
			break;
		}	

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