“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图1所示。
假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
输入格式:
输入第1行给出两个正整数,分别表示社交网络图的结点数N(1<N≤
,表示人数)、边数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的节点,很容易想到BFS
难点在于节点与该点间隔层数的计算
解法一:用tail临时标记当前遍历的最后一个节点,last记录该层的最后一个节点,如果当前处理完毕的节点为last,则该层已处理完毕,下一个要处理的节点为下一层的节点,此时tail标志下一层的最后一个节点,令last=tail,层数level+1。
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
vector<vector<int>> Adj; //邻接表
vector<bool> inq; //节点是入队
int BFS(int v){
inq[v] = true;
queue<int> q;
q.push(v);
int count = 1,level = 0; //初始化距离不超过6的结点数和层数
int tail,last = v; //tail为每层最后一个节点的临时标志,tail为每层最后一个节点,初始化0层的最后一个节点为v
while(!q.empty()){
int tmp = q.front();
q.pop();
for(int i = 0; i < Adj[tmp].size(); i++){//遍历所有邻接点
int w = Adj[tmp][i];
if(!inq[w]){//未被访问
q.push(w); //邻接点入队
count++;
inq[w] = true; //标记已访问
tail = w; //最后一个节点的临时标志
}
}
if(tmp == last){ //当前访问完毕的节点为该层最后一个节点,则level+1,此时下一层的节点已全入队,更新last
level++;
last = tail;
}
if(level == 6) break;
}
return count;
}
int main()
{
int n,m,x,y;
cin>>n>>m;
Adj.resize(n+1);
inq.resize(n+1);
for(int i = 0; i < m; i++){//建立边
cin>>x>>y;
Adj[x].push_back(y);
Adj[y].push_back(x);
}
int count;
for(int i = 1; i <= n; i++){
inq.assign(n+1,false); //设置未被访问
count = BFS(i);
printf("%d: %.2f%\n",i,((double)count/n)*100);
}
return 0;
}
解法二:用结构体存储编号和相应层数,则每个相邻节点的层数为当前节点层数+1.
#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct Node{
int id,layer;
};
vector<vector<int>> Adj;
vector<bool> inq;
int BFS(Node tnode){
queue<Node> q;
q.push(tnode); //入队
inq[tnode.id] = true; //设置已入队
int count = 1;
while(!q.empty()){
Node top = q.front();
q.pop();
for(int i = 0; i < Adj[top.id].size(); i++){
int nextId = Adj[top.id][i];
if(!inq[nextId] && top.layer < 6){
Node next = {nextId, top.layer + 1};
q.push(next);
inq[nextId] = true; //设置已入队
count++;
}
}
}
return count;
}
int main(){
int n,m,x,y;
cin>>n>>m;
Adj.resize(n+1);
inq.resize(n+1);
for(int i = 0; i < m; i++){
cin>>x>>y;
Adj[x].push_back(y);
Adj[y].push_back(x);
}
int count;
for(int i = 1; i <= n; i++){
inq.assign(n+1,false);
Node tnode = {i, 0}; //初始化节点的层数为0
count = BFS(tnode);
printf("%d: %.2f%\n",i,((double)count/n)*100);
}
}