【PTA】六度空间 (30 分)

该博客介绍了如何使用宽度优先搜索(BFS)和深度优先搜索(DFS)遍历图,并提供了C++代码示例。通过BFS计算节点的访问百分比,同时展示了两种不同的BFS实现方式。此外,还讨论了DFS在遍历过程中可能遇到的问题,即可能丢失单通路节点。

 

//只能使用BFS
#include <iostream>
#include <queue>
#define MAXN 1010
using namespace std;

//其实比较稀疏,且每个结点的邻接点已经给出,最好使用邻接表
int N,M;
int G[MAXN][MAXN];

int visited[MAXN];
//让BFS返回每个vetex的计数,就不用多开一个数组了
int BFS(int vetex){
    int sum=0;
    int level=0,last=vetex;
    queue<int> q;
    q.push(vetex);sum++;
    visited[vetex]=1;

    int tmp,tail;
    while(!q.empty()){
        tmp=q.front();
        q.pop();

        for(int j=0;j<N;j++){
            if(G[tmp][j]==1 && !visited[j]){
                q.push(j);sum++;
                visited[j]=1;
                tail=j;//tail:tmp的最后一个邻接点
            }
        }
        if(tmp == last){
//last:本层最后一个结点
//本层结束
            last=tail;//本层最后一个结点的最后一个邻接点
            level++;
        }
//第7层时退出
        if(level == 6) break;
    }
    return sum;
}


int main(){
    cin>>N>>M;

    int v1,v2;
    for(int i=0;i<M;i++){
        cin>>v1>>v2;

        G[v1-1][v2-1]=1;
        G[v2-1][v1-1]=1;
    }

    for(int i=0;i<N;i++){
        printf("%d: %.2f%\n",i+1,100.0*BFS(i)/N);
//每次BFS完记得清零
        fill(visited,visited+N,0);
    }


    return 0;
}
//BFS+depth第二种方法
#include <bits/stdc++.h>
using namespace std;

#define MAXN 1010
int nv,ne;
int G[MAXN][MAXN];

struct node
{
    int index,depth;
};

int visited[1010];
int bfs(int root){
    queue<node> q;
    q.push(node{root,0});
    visited[root]=root;

    int cnt=0;
    while(!q.empty()){
        node tmp=q.front();
        q.pop();

        if(tmp.depth>6) break;
        else cnt++;
        
        for(int i=1;i<=nv;i++){
            if(G[tmp.index][i]!=0 && visited[i]!=root){
                q.push(node{i,tmp.depth+1});
                visited[i]=root;
            }
        }
    }
    return cnt;
}

int main(){
    scanf("%d %d",&nv,&ne);

    int t1,t2;
    for(int i=0;i<ne;i++){
        scanf("%d %d",&t1,&t2);
        G[t1][t2]=1;
        G[t2][t1]=1;
    }
    for(int i=1;i<=nv;i++){
        printf("%d: %.2f%\n",i,100.0*bfs(i)/nv);
    }
    return 0;
}

 

//每次sum++是对的,
//但visit退回时却没有返回上一层,因此由于访问顺序可能会缺失单通路的结点
#include <iostream>
#define MAXN 1010
using namespace std;

int G[MAXN][MAXN];
int nv,ne;

void CreateG(){
    int v1,v2;
    for(int i=0;i<ne;i++){
        cin>>v1>>v2;
        G[v1-1][v2-1]=1;
        G[v2-1][v1-1]=1;
    }
}

int visited[MAXN];
int sum=1;
void DFS(int vetex,int level){
    if(level==6) return;
    visited[vetex]=1;
    for(int j=0;j<nv;j++){
        if(!visited[j] && G[vetex][j]==1){
            sum++;
            DFS(j,level+1);
        }
    }
}

int main(){
    cin>>nv>>ne;
    CreateG();
    for(int i=0;i<nv;i++){
        DFS(i,0);
        printf("%d: %.2f%\n",i+1,100.0*sum/nv);
        fill(visited,visited+nv,0);
        sum=1;
    }

    system("pause");
    return 0;
}

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值