PTA-社交网络图中结点的“重要性”计算(并查集+bfs)
思路:先判断一下是否是连通图,否的话就直接输出0.00,否则bfs。
另外注意不要用二维数组去存点和点之间的关系,会超内存,可以用vector容器。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <string> #include <cmath> #include <queue> #include <map> #include <vector> #define INF 0x3f3f3f3f using namespace std; int n,m; vector<int>e[10010];//用二维数组交的时候超内存 bool book[10010]; int num[10010];//记录从开始点到该点的路的最少条数 //并查集判断是否为连通图 int Boss[10010]; int Find(int x) { if(Boss[x]!=x) Boss[x]=Find(Boss[x]); return Boss[x]; } int Merge(int x,int y) { int u=Find(x); int v=Find(y); if(u!=v) Boss[u]=v; } //搜索 int dfs(int x) { memset(book,false,sizeof(book)); memset(num,INF,sizeof(num)); num[x]=0; queue<int>Q; Q.push(x); while(!Q.empty()) { int now=Q.front(); Q.pop(); book[now]=true; int s=e[now].size(); for(int i=0; i<s; i++) { int point=e[now][i]; if(!book[point]) { Q.push(point); if(num[point]>=num[now]+1) num[point]=num[now]+1; } } } int sum=0; for(int i=1; i<=n; i++) sum+=num[i]; return sum; } int main() { cin>>n>>m; memset(e,0,sizeof(e)); for(int i=0; i<=n; i++) Boss[i]=i; for(int i=0; i<m; i++) { int u,v; cin>>u>>v; e[u].push_back(v); e[v].push_back(u); Merge(u,v); } int Count=0; for(int i=1; i<=n; i++) if(Boss[i]==i) Count++; int k,x; cin>>k; for(int i=0; i<k; i++) { cin>>x; double temp=0; if(Count==1)//当为连通图时 { temp=(double)dfs(x); temp/=(double)(n-1); temp=1.0/temp; } printf("Cc(%d)=%.2lf ",x,temp); } return 0; }