http://www.patest.cn/contests/mooc-ds/05-3
题目中有10000个点,边更多,若用邻接矩阵,双重循环必超时,因此用vector
遍历还是用模板
错误一:dfs遍历,最后一个点不过
由于dfs调用系统栈,最多15000,而边可能会有很多,所以不过
错误二:什么时候层数更新
改用bfs,用tail不断记录队尾,用last表示本层的最后一个节点,只有当出队者k与last等同时,表示本层已经刷完,更新last为新的tail,并更新层数
注意,应该先入队,入队后检查是否更新,这样才能得到最新的
void bfs(int x){
int cnt=0;
que.push(x);
visit[x]=1;
dis[x]=cnt;
int last=x;
int tail=x;
cnt++;
while(que.empty()==0){
int k=que.front();
que.pop();
for(int i=1;i<=edge[k].size();i++){
int j=edge[k][i-1];
if(visit[j]==0){
que.push(j);
visit[j]=1;
dis[j]=cnt;
tail=j;
}
}
if(k==last){
last=tail;
cnt++;
}
}
}
#include <stdio.h>
#define MAX 10010
#include <vector>
#include <queue>
using namespace std;
vector <int> edge[MAX];
int dis[MAX];
bool visit[MAX];
queue <int> que;
void init(){
for(int i=1;i<MAX;i++){
visit[i]=0;
dis[i]=-1;
}
}
void dfs(int x,int cnt){
cnt++;
dis[x]=cnt-1;
visit[x]=1;
for(int i=1;i<=edge[x].size();i++){
int j=edge[x][i-1];
if(visit[j]==0){
dfs(j,cnt);
}
}
}
//注意求层数时,使用last和tail记录新一层
void bfs(int x){
int cnt=0;
que.push(x);
visit[x]=1;
dis[x]=cnt;
int last=x;
int tail=x;
cnt++;
while(que.empty()==0){
int k=que.front();
que.pop();
for(int i=1;i<=edge[k].size();i++){
int j=edge[k][i-1];
if(visit[j]==0){
que.push(j);
visit[j]=1;
dis[j]=cnt;
tail=j;
}
}
if(k==last){
last=tail;
cnt++;
}
}
}
int main(){
freopen("in.txt","r",stdin);
int dian,bian;
while(scanf("%d %d",&dian,&bian)!=EOF){
for(int i=1;i<=dian;i++){
edge[i].clear();
}
for(int i=1;i<=bian;i++){
int a,b;
scanf("%d %d",&a,&b);
edge[a].push_back(b);
edge[b].push_back(a);
}
for(int i=1;i<=dian;i++){
init();
int cnt=0;
if(visit[i]==0){
//dfs(i,cnt);
bfs(i);
}
int ans=0;
for(int j=1;j<=dian;j++){
if(dis[j]>=0&&dis[j]<7){
ans++;
}
}
double tmp=(double)ans/dian;
tmp*=100;
printf("%d: %2.2lf%%\n",i,tmp);
}
}
}