BJFUOJ[代码原创附思路] 284 基于深度优先搜索的两顶点路径存在与否的判断

描述

设计一个算法,试基于深度优先搜索判断以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(i≠j)。

输入

多组数据,每组m+3数据行。第一行有两个数字n和m,代表有n个顶点和m条边。第二行有n个字符,代表n个顶点的编号。第三行到第m+2行每行有两个字符h和k,代表边依附的两个顶点。第m+3行有两个字符vi和vj,代表需要判断的两个顶点。当n和m都等于0时,输入结束。

输出

每组数据输出一行。若存在路径输出“YES”,反之输出“NO”。


数据结构定义:
邻接表的结构如下:
以题目提供的第一个输入为例:
abc
ab
bc
[头结点a]->[b]->NULL
[头结点b]->[c]->NULL
[头结点c]->NULL

//定义结点类型ANode:

typedef struct ANode {
    char val;
    ANode* next;
} ANode, *Alist;

//定义邻接表:

typedef struct AGraph {
    unordered_map<char,Alist>List; //unordered_map:字典类型
    int vnum, anum;                //其中的边数量anum似乎没啥用
} AGraph;

邻接表的初始化与根据输入的创建:

void create(AGraph& AG, int vn, int an) {
    AG.vnum = vn,AG.anum = an;            //anum其实是用不到的
    string vlist;cin>>vlist;
    for(int i = 0;i < vn;i ++){
        AG.List[vlist[i]] = new ANode;    //unordered_map中,前者相当于数组的下标索引
        AG.List[vlist[i]]->next = NULL;   //索引类型char,数据类型Alist,这里不难理解
    }
    
    for(int i = 0;i < an;i ++){
        string v2v;cin>>v2v;              //v2v意思就是vertex to vertex,点到点
        ANode *p = new ANode;
        p->val = v2v[1];                  //头插法,可以使用尾插法,不过需要找到链表尾部
        p->next = AG.List[v2v[0]]->next;
        AG.List[v2v[0]]->next = p;
    }
}

深度优先搜索DFS和入口函数solution:

void DFS(AGraph& G,char vertex,unordered_map<char,bool>& visited,char targetV,bool &isFound){//bool值需要使用地址引用,不然的话传入的参数是个形参,无法在solution中发生改变
/*
   在邻接表中进行深度优先的思路就是:
   结点是否有->next?(例如[头结点a]->[b]->NULL)
     --有:进入到->next结点(即b)
   然后进入[头结点b]的深度优先

   假设是到了[b]->NULL,于是递归会返回,进入到后面的[b]->next(也就是NULL)中
*/
    visited[vertex] = true;
    
    ANode* currNode = G.List[vertex]->next;
    while(currNode){
        char nextVertex = currNode->val;//注意,这里保存的不是下一个结点本身,而是结点索引
        if(nextVertex == targetV){
            isFound = true;
        }
        if(!visited[nextVertex]){
            DFS(G,nextVertex,visited,targetV,isFound);
        }
        currNode = currNode->next;
    }
}

void solution(AGraph& AG){//入口函数
    char beginV,targetV;
    cin>>beginV>>targetV;
    unordered_map<char,bool>visited;
    for(auto it = AG.List.begin();it != AG.List.end();it ++){
        visited[it->first] = false;//visted经过初始化完成后,就是visited[a] or [b] or [c] = false
    }
    bool isFound = false;
    DFS(AG,beginV,visited,targetV,isFound);
    if(isFound){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }
}

main函数:

int main() {
    int vn, an;
    cin >> vn >> an;
    while (vn != 0 || an != 0) {
        AGraph AG;
        create(AG, vn, an);
        solution(AG);
        cin >> vn >> an;
    }
    return 0;
}

完整代码如下:

#include<bits/stdc++.h>
using namespace std;

typedef struct ANode {
    char val;
    ANode* next;
} ANode, *Alist;

typedef struct AGraph {
    unordered_map<char,Alist>List;
    int vnum, anum;
} AGraph;

void create(AGraph& AG, int vn, int an) {
    AG.vnum = vn,AG.anum = an;
    string vlist;cin>>vlist;
    for(int i = 0;i < vn;i ++){
        AG.List[vlist[i]] = new ANode;
        AG.List[vlist[i]]->next = NULL;
    }
    
    for(int i = 0;i < an;i ++){
        string v2v;cin>>v2v;
        ANode *p = new ANode;
        p->val = v2v[1];
        p->next = AG.List[v2v[0]]->next;
        AG.List[v2v[0]]->next = p;
    }
}

void DFS(AGraph& G,char vertex,unordered_map<char,bool>& visited,char targetV,bool &isFound){
    visited[vertex] = true;
    
    ANode* currNode = G.List[vertex]->next;
    while(currNode){
        char nextVertex = currNode->val;
        if(nextVertex == targetV){
            isFound = true;
        }
        if(!visited[nextVertex]){
            DFS(G,nextVertex,visited,targetV,isFound);
        }
        currNode = currNode->next;
    }
}

void solution(AGraph& AG){
    char beginV,targetV;
    cin>>beginV>>targetV;
    unordered_map<char,bool>visited;
    for(auto it = AG.List.begin();it != AG.List.end();it ++){
        visited[it->first] = false;
    }
    bool isFound = false;
    DFS(AG,beginV,visited,targetV,isFound);
    if(isFound){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }
}


int main() {
    int vn, an;
    cin >> vn >> an;
    while (vn != 0 || an != 0) {
        AGraph AG;
        create(AG, vn, an);
        solution(AG);
        cin >> vn >> an;
    }
    return 0;
}

  • 17
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值