4002六度空间理论

描述

“六度空间”理论又称作“六度分隔(Six Degrees of Separation)”理论。这个理论可以通俗地阐述为:“你和任何一个陌生人之间所间隔的人不会超过六个,也就是说,最多通过五个人你就能够认识任何一个陌生人。”假如给你一个社交网络图,请你对每个节点计算符合“六度空间”理论的结点占结点总数的百分比。

输入

多组数据,每组数据m+1行。第一行有两个数字n和m,代表有n个人和m组朋友关系。n个人的编号为1到n。第二行到第m+1行每行包括两个数字a和b,代表这两个人互相认识。当n和m都等于0时,输入结束。

输出

每组数据输出n行,对每个结点输出与该结点距离不超过6的结点数占结点总数的百分比,精确到小数点后2位。每个结节点输出一行,格式为“结点编号:(空格)百分比%”。

输入样例 1 

10 9
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 8
1 2
2 3
3 4
4 5
5 6
6 7
7 8
9 10
0 0

输出样例 1

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%
1: 70.00%
2: 80.00%
3: 80.00%
4: 80.00%
5: 80.00%
6: 80.00%
7: 80.00%
8: 70.00%
9: 20.00%
10: 20.00%
//六度空间理论
#include <iostream>
#include <iomanip>
#define MVNum 100//最大顶点数 
using namespace std;
typedef struct{
	int vexs[MVNum];//顶点表 
	int arcs[MVNum][MVNum];//邻接矩阵
	int vexnum,arcnum; 
}AMGraph;
void Create_V(AMGraph &G,int name){
	int pos=++G.vexnum;
	G.vexs[pos-1]=name;//存入点名 
	for(int i=1;i<=pos;i++){//点所在的行列清零 
		G.arcs[i-1][pos-1]=0;
		G.arcs[pos-1][i-1]=0;
	}
}
void Create_Arc(AMGraph &G,int h,int k){
	G.arcs[h-1][k-1]=G.arcs[k-1][h-1]=1;//点与对称点都归1 
	G.arcnum++;
}
void Search(AMGraph &G,int path[],int i,int deep){//输入图、路径数组、用于查找的顶点、当前深度 
	if(deep==6) return;//如果到达6度就退出 
	for(int j=1;j<=G.vexnum;j++)//遍历每个结点 
		if(G.arcs[i-1][j-1]==1&&path[j-1]==0){//遇到未经过的可达的顶点时对那个顶点进行Search,并且深度+1,同时改变他的path为1(来过) 
			path[j-1]=1;
			Search(G,path,j,deep+1);
		}
			
}
void SDoS(AMGraph &G){//Six Degrees of Separation 六度空间理论 
	for(int i=1;i<=G.vexnum;i++){
		int path[G.vexnum]={0};//路径数组,用于记录哪些顶点是六度之内可达的 
		path[i-1]=1;//将自己标记为可达 
		Search(G,path,i,0); //查找可达顶点并改变path内的值 
		int sum=0;//用于统计六度之内到达过的顶点数量 
		for(int j=1;j<=G.vexnum;j++) sum+=path[j-1]; 
		sum*=100; //为后面百分号计算做准备 
		cout<<G.vexs[i-1]<<": ";
		cout<<fixed<<setprecision(2)<<1.0*sum/G.vexnum<<"%"<<endl;
	}
}
void Calculate(int m,int n){
	AMGraph G;
	G.vexnum=G.arcnum=0;
	for(int i=1;i<=m;i++) Create_V(G,i);//构造前n个顶点 
	for(int i=1;i<=n;i++){//构造n条边 
		int h,k;
		cin>>h>>k;//输入左右顶点
		Create_Arc(G,h,k);//构造边
	}
	SDoS(G); 
}
int main(){
	int m,n;
	while(cin>>m>>n&&m!=0&&n!=0){//每次处理一行数据 
		Calculate(m,n);
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘下来邦我吧

头发加了一根

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值