题目:http://pta.patest.cn/pta/test/15/exam/4/question/715
PTA - 数据结构与算法题目集(中文)- 5-7
“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”如图6.4所示。
图6.4 六度空间示意图
假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。
输入格式说明:
输入第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 <iostream> #include <fstream> #include <cstdio> #include <queue> #include <vector> using namespace std; const int maxn=10005; int vertices, edges; vector<int> G[maxn]; //每个vector结构的元素表示:与数组下标代表的结点有边的结点 bool vis[maxn]; //是否访问过 int BFS(int v) { for(int i=0; i<maxn; i++) vis[i]=false; int tail; //用于记录每层压入时的结点 int last=v; //记录每层的最后一个元素:该层压入之后弹出之前更新:last=temp; int count=1; int level=0; vis[v]=true; queue<int> q; q.push(v); while(!q.empty()) { int x=q.front(); //弹出x q.pop(); for(int j=0; j<G[x].size(); j++) //x的一圈压入队列 { if(!vis[G[x][j]]) //若未被访问过:访问并压入队列 { vis[G[x][j]]=true; q.push(G[x][j]); tail=G[x][j]; //记录压入的结点 count++; } } if(x==last) //一层全部弹出,准备开始弹下一层:弹出的(x)=当前层最后一个元素(last) { last=tail; //一层全都压入完后,更新last level++; } if(level==6) break; } return count; }
int main(int argc, char** argv) { int x,y; cin >> vertices >> edges; //ifstream fin("test.txt"); //fin >> vertices >> edges; for(int i=1; i<=edges; i++) { cin >> x >> y; //fin >> x >> y; G[x].push_back(y); G[y].push_back(x); } for(int j=1; j<=vertices; j++) { //cout << BFS(j) << endl; printf("%d: %.2lf%% ", j, BFS(j)*1.0/vertices*100.0); //格式输出 } return 0; }