图的操作

Q129.(10分)图的操作:
1.图的存储结构使用邻接矩阵。
2.创建图操作类,支持BFS遍历、DFS遍历、求单源最短路径、求最小生成树、判断是否存在回路等五个功能,这些功能封装成图操作类的成员函数
3. 采用“起始节点,终止节点,权值”输入图的m条边,创建图。
4. 输出从节点1开始的BFS遍历、DFS遍历节点遍历顺序。
5. 输出从节点1到其余节点的最短路径及最短路径长度,如果没有路径,输出0。
6.  输出图的最小生成树包含的边,边用“起始节点,终止节点,权值”表示。
输入输出说明:
输入:
第1行输入2个整数,图的节点数n(不超过10个)、边数m。
接下来m行,每行3个整数。采用“起始节点,终止节点,权值”输入图的m条边。
输出:
第1行为图的BFS遍历
第2行为图的DFS遍历
接下来n-1行,为图中第1个节点到其他节点的最短路径,如果没有路径,路径长度输出“0”。格式为:最短路径 路径长度。
接下来输出图的最小生成树包含的边,边用“起始节点,终止节点,权值”表示,按权值从小到大输出最小生成树的边。
最后一行输出大写字母 YES 或 NO:YES代表图中有环,NO代表图中无环。
输入:
6 9
1 2 10
1 4 20
1 6 2
2 3 3
2 4 5
3 5 15
4 5 11
4 6 10
5 6 3
输出:
1 2 4 6 3 5
1 2 3 5 4 6
1 2 10
1 2 3 13
1 6 4 12
1 6 5 5
1 6 2
1 6 2
2 3 3
5 6 3
2 4 5
1 2 10
YES

 

 

 

首先,兵荒马乱后的代码,为了提交oj,不知道自己写了个什么玩意。

1、另外,一定要读题:我最先一直认为这是有向图,虽然他有起点终点,但是带入测试样例,居然是无向图。

就这一个地方,加上matrix[v1][v2]=matrix[v2][v1]就可以了,调了好久。

2、Dijstra和MST的代码不知道怎么搞得,糟糕。

3、并且之里面还有个很烦的地方:就是结点从1开始,后面的for循环全部都有n+1;或者最开始存的时候要减-1。

#include <iostream>
#include <assert.h>
#include <queue>
#include <memory.h>
#include <algorithm>
using namespace std;
int INFINITY =9999999;
class Graphm{
private:
    int INFINITY = 9999999;
    int numVertex, numEdge;
    int count=0;
    int *mark;
    //int mat[100][100]={{0}};
    //int **p = mat;
    //书上的代码是从0开始,而符合题目从1开始——特别注意!!!!! 所以涉及的话都要加1,特别注意


    void DFS(int v){
        cout<<v<<" "; //??????
        this->setMark(v,1);
        for (int w=this->first(v); w<this->n()+1;w=this->next(v,w)){  //注意,承接上面,这里要加1
            if (this->getMark(w) == 0)
                DFS(w);
        }
    }
    void BFS(int start, queue<int>* Q ){
        int v,w;
        Q->push(start);
        this->setMark(start,1);
        while (Q->size()!=0){
            v = Q->front();
            Q->pop();
            if(count!=n()-1) {cout<<v<<" ";count+=1;}//?????实现Previsit式的输出
            else cout<<v;
            for (w=this->first(v); w<this->n()+1; w=this->next(v,w)) //+1;
                if (this->getMark(w)==0){
                    this->setMark(w,1);
                    Q->push(w);
                }
        }

    }
    int helpfindcircle(int v, int h){
        setMark(v,1);
        for (int w = first(v); w<n()+1; w = next(v,w)){
            if(getMark(w)==1 && w!=h)
                return 1;
         else if (getMark(w)==0)
                if(helpfindcircle(w,v))
                    return 1;
        }
        return 0;
    }

public:
    int **matrix;
    void Init(int n){
        numVertex = n;
        numEdge = 0;
        mark = new int[n+1];
        for (int i=1;i<=numVertex;i++)
            mark[i] = 0;  //UNVISITED
        matrix = (int**) new int*[numVertex+1];
        for(int i=1;i<=numVertex;i++)  //这里可以不从0开始
            matrix[i]=new int[numVertex+1];
        for (int i=1; i<numVertex+1;i++)
            for (int j=1;j<numVertex+1;j++)
                matrix[i][j]=0;
    }

    Graphm(int numVert){
        Init(numVert);
    }

    ~Graphm(){
        delete []mark;
        for (int i=0;i<numVertex+1;i++)  //+1
            delete []matrix[i];
        delete []matrix;
    }

    int n(){return numVertex;}
    int e(){return numEdge;}

    int first(int v){//第一个邻居
        for (int i=1;i<numVertex+1;i++) //+1
            if (matrix[v][i]!=0) return i;
        return numVertex+1;//如果没有直接返回n+1;------非常巧妙,在下面的遍历中终止条件就是<numVertex+1,大于说明一定没有邻居
    }
    int next(int v, int w){//w后v的下一个邻居
        for (int i=w+1;i<numVertex+1;i++)
            if (matrix[v][i]!=0)
                return i;
        return numVertex+1;//没有,返回n+1 -------非常巧妙,在下面的遍历中终止条件就是<numVertex+1,大于说明一定没有邻居
    }

    void setEdge(int v1, int v2, int wt){
        //Assert(wt>0, "illegal weight value.");
        if (matrix[v1][v2] == 0) numEdge++;
        matrix[v1][v2] = matrix[v2][v1]=wt;
    }
    void delEdge(int v1, int v2){
        if (matrix[v1][v2]!=0) numEdge--;
        matrix[v1][v2]=0;
    }
    bool isEdge(int i, int j){ //判断i,j之间是否有边
        return matrix[i][j]!=0;
    }
    int weight(int v1, int v2){return matrix[v1][v2];}
    int getMark(int v){return mark[v];}
    void setMark(int v, int val){mark[v]=val;}

    void graphTraverse1(){//DFS

        for (int v=1;v<this->n()+1;v++) //+1
            this->setMark(v,0); //首先全部都标记未访问
        for (int v=1;v<this->n()+1;v++) //+1
                                         //从1开始,一个一个遍历
            if (this->getMark(v)==0)
                DFS(v);
        cout<<endl;
    }

    void graphTraverse2(int start){ //宽搜的开始
        count=0;
        for (int v=1;v<this->n()+1;v++) //+1
            this->setMark(v,0); //首先全部都标记未访问
        queue<int>* Q = new queue<int>;
        for(int i=1;i<numVertex+1;i++)
            if(getMark(i)==0) BFS(start,Q);
        cout<<endl;
    }







    /*int[] get(int s){
        int D[this->n()+1];
        for (int i=1;i<this->n()+1;i++){
             D[i]=INFINITY;
        }
        for (int i=1;i<n();i++)
           setMark(i,0);     //根本就可以不用this指了
        return D;
    }*/

   /* void Dijkstra(int* D, int s){
        int i,v,w;

        D[s] = 0;
        for(i = 1; i<n()+1; i++)
            setMark(i,0);

        for (i=1; i<numVertex+1; i++){
            v = minVertex(D);
            if (D[v]==INFINITY) return;
            setMark(v,1);
            for (w = first(v); w<n()+1; w=next(v,w))
                if(D[w] > (D[v]+weight(v,w)))
                    D[w] = D[v]+weight(v,w);
        }
    }*/




   /* void dijkstra( int* D) {
            int* vis = new int[numVertex+1];
            int pre[numVertex+1];
            int k;
           for (int i=1;i<n()+1;i++)
               vis[i]=0;

            for (int i = 1; i <= n(); i++) {
                D[i] = 1000000;
            }
            D[1] = 0;
            pre[1] = 0;
            vis[1] = 1;
            for (int i = 1; i <= n(); i++) {
                if (matrix[1][i] != 0) {
                    D[i] = matrix[1][i]; pre[i] = 1;
                }
            }
            for (int i = 1; i <= n()-1; i++) {
                int minn = 1000000;
                for (int j = 1; j <= n(); j++) {
                    if (minn > D[j] && vis[j] == 0) {
                        minn = D[j];
                        k = j;
                    }
                }//找出目前最小的一个点
                vis[k] = 1;
                for (int j = 1; j <= n(); j++) {
                    if (vis[j] == 0 && d[j] > d[k] + graph[k][j]&&graph[k][j]!=0) {
                        d[j] = d[k] + graph[k][j];
                        pre[j] = k;
                    }
                }
            }
            for (int i = 2; i <= N; i++) {
                string s = "";
                s = getstring(d[i]);
                int x = i;
                while (x != 0) {
                    s = getstring(x) + " " + s;
                    x = pre[x];
                }
                cout <<s<< endl;
            }
        }
        string getstring(int x) {
            string s = "";
            int z = x;
            char c;
            while (z > 0) {
                c = z % 10 + '0';
                z /= 10;
                s = c + s;
            }
            return s;
        }*/
    int minVertex(int* D){
        int i, v=-1;
        for (i=1; i<this->n()+1;i++)
            if (this->getMark(i) == 0) {v=i;break;}
        for (i++;i<this->n()+1;i++)
            if(this->getMark(i)==0 && (D[i]<D[v]))
                v=i;
        return v;
    }




    /*void isLoop(){
        for (int v=1;v<this->n()+1;v++) //+1
            this->setMark(v,0); //首先全部都标记未访问
        for (int v=1;v<this->n()+1;v++) //+1
                                         //从1开始,一个一个遍历
            if (this->getMark(v)==0)
                DFS(v);


    }*/

    bool isLoop(){
        int i;
        for(i=1;i<numVertex+1;i++)
            setMark(i,0);
        for(i=1;i<n()+1;i++)
            if(getMark(i)==0)
            {
                if (helpfindcircle(i,-1)==1)
                    return true;
            }
        return false;
    }
    void PreVisit(int v){
            cout<<v<<' ';
    }

   /* void helpDFS(int v) {
            PreVisit(v);
            setMark(v, 1);
            for (int w=first(v); w<numVertex+1; w = next(v,w))
                if (getMark(w) == 0)
                    helpDFS(w);
        }
    void Dfs(){
            int i;
            for(i=1;i<numVertex+1;i++)
                setMark(i,0);
            for(int i=1;i<numVertex+1;i++)
                    if(getMark(i)==0)
                        helpDFS(i);
            cout<<endl;

        }*/
    void Dfs() {
        count=0;
        for(int i=1;i<numVertex+1;i++)
            setMark(i,0);
            for (int i = 1; i <= n(); i++) {
                if (getMark(i)==0) {
                    dfs(i);
                }
            }
            cout << endl;
        }
        void dfs(int u) {
            setMark(u,1);
            if(count!=n()-1) {cout<<u<<" ";count+=1;}//?????实现Previsit式的输出
            else cout<<u;
            for (int i = 1; i <= n(); i++) {
                //if (getMark(i)==1) flag = 1;
                if (getMark(i) == 0 && matrix[u][i] != 0) {
                    dfs(i);
                }
            }
        }

};


int N;
int d[10000];
int vis[10000]={0};
int pre[10000]={0};
int k;
string getstring(int x) {
    string s = "";
    int z = x;
    char c;
    while (z > 0) {
        c = z % 10 + '0';
        z /= 10;
        s = c + s;
    }
    return s;
}
void dijkstra(int **graph) {
        memset(vis, 0, sizeof(vis));
        //cout << "输出1到剩余各节点的最短路径" << endl;
        for (int i = 1; i <= N; i++) {
            d[i] = 1000000;
        }
        d[1] = 0;
        pre[1] = 0;
        vis[1] = 1;
        for (int i = 1; i <= N; i++) {
            if (graph[1][i] != 0) {
                d[i] = graph[1][i]; pre[i] = 1;
            }
        }
        for (int i = 1; i <= N-1; i++) {
            int minn = 1000000;
            for (int j = 1; j <= N; j++) {
                if (minn > d[j] && vis[j] == 0) {
                    minn = d[j];
                    k = j;
                }
            }//找出目前最小的一个点
            vis[k] = 1;
            for (int j = 1; j <= N; j++) {
                if (vis[j] == 0 && d[j] > d[k] + graph[k][j]&&graph[k][j]!=0) {
                    d[j] = d[k] + graph[k][j];
                    pre[j] = k;
                }
            }
        }
        for (int i = 2; i <= N; i++) {
            string s = "";
            s = getstring(d[i]);
            int x = i;
            while (x != 0) {
                s = getstring(x) + " " + s;
                x = pre[x];
            }
            cout <<s<< endl;
        }
    }


struct e{
    int x,y;
    int w;
}E[3002];
int pres[1002]={-1};

bool cmp(e e1, e e2){
    return e1.w< e2.w;
}

int find(int i){
    if (pres[i]==-1) return i;
    else return pres[i]=find(pres[i]); //这一步很巧妙,如果直接return find(pre[i]),则只是找到了根节点罢了,
                                     //但是这样写,找到的同时,又全部在这一过程中压缩了路径,使其全部都等于根节点了。

}
void Add(e e1){
    int y = find(e1.x);
    int y2 = find(e1.y);
    //pre[e1.x] = y2; 这是错的!!!! 要从根节点上改变,否则是错误的只是将当前这个结点又换了一个根罢了
    pres[y] =y2;
}


int main()
{
    cin>>N;
    int m;
    cin>>m;
    Graphm g(N);
    //int s,e,w;
    for(int i=0;i<m;i++){
        cin>>E[i].x>>E[i].y>>E[i].w;
        g.setEdge(E[i].x,E[i].y,E[i].w);
    }

    //cout<<"-----------"<<endl;
    g.graphTraverse2(1); //从1开始
    g.Dfs();

    dijkstra(g.matrix);

    memset(pres,-1,sizeof(pres));
    sort(E,E+m,cmp);




    //cout<<"-----------------"<<endl;
    //int weight=0;
    int count=0;
    for (int i=0;i<m;i++){


        int a = find(E[i].x);
        int b = find(E[i].y);

        if (a!=b){
            count+=1;
            //cout<<count<<":"<<a<<"-"<<b<<" ";
            Add(E[i]);

            //weight+=E[i].w;
            cout<<E[i].x<<" "<<E[i].y<<" "<<E[i].w<<endl;
            if (count==N-1) break; //边足够了

    }

}
    bool ans = g.isLoop();
    if (ans) cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
    return 0;
}

第二天改证重写,注释在其中,很详细了

//写完后,感觉有点不足的是,Prim算法里面存边没有用矩阵,还是用了strcut结构体来存,好像跟这个图使用矩阵实现有点别扭。
//并且,我增加了许多私有变量,为了方便我的实现。
#include <iostream>
#include <queue>
#include <algorithm>
#include <memory.h>
using namespace std;

//由题意:1、无向图 --矩阵对称 2、只有为正的路径(否则哪来的输出0)---0为表示是否有边存在
class Graphm{
 //第一次写的时候:对类里面的操作不够熟悉1、在所有的操作上在this,并且没有直接用变量---多此一举,本来就是默认this
 //              2、在函数内部应该直接使用私有变量,封装的public函数应该是对外面的,私有公有都是面向外面的。
 //使用下标开始的问题:题目是从1开始,①下标从1,不过所有for循环都要加一,---很容易忘(第一次)
 //                             ②还是从0,在输入的时候-1,输出的时候加1(这次)
 private:
    int numVertex,numEdge;
    int (**matrix);
    int *mark;   //我不知道为啥要用指针,这两项

    int INFINITY = 99999999;
    int cnt=0;//辅助
    //记录被选上的边
    struct e{
        int s;
        int e;
        int w;
    };
    int *father;

public:
    Graphm(int n){
        numVertex = n;
        numEdge=0;

        matrix =(int **) new int*[n];//这句话一定要在下一句话的前面
        for(int i=0;i<n;i++)
            matrix[i]=new int[n];  //注意二维矩阵的初始

        for (int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                matrix[i][j]=0;
        mark= new int[n];
    }

    ~Graphm(){
        for (int i=0;i<numVertex;i++)
            delete []matrix[i];
        delete []matrix;
        delete []mark;
    }

public:
    //我觉得这都是外面操作的,实际在类里面不用这么操作
    void setMark(int v, int val){mark[v]=val;}
    int getMark(int v) {return mark[v];}
    void setEdge(int v1, int v2, int weight){
        if (matrix[v1][v2]==0) numEdge++;//非常严谨的思路
        matrix[v1][v2] = matrix[v2][v1] =  weight; //顺便还可以改变已有的  //无向图与有向图区别
    }
    void delEdge(int v1, int v2){
        matrix[v1][v2] = matrix[v2][v1]=0;       //无向图与有向图区别
    }
    int weight(int v1, int v2){
        return matrix[v1][v2];
    }
    bool isEdge(int v1, int v2){
        if (matrix[v1][v2]!=0) return true;
        return false;
    }
    int n(){return numVertex;}
    int e(){return numEdge;}


    //下面才是题目要求实现的函数,并且会用到的封装函数
    //为了方便操作而封装:
    int first(int v){   //找到v的第一个邻居:是从坐标来看的
        for (int i=0;i<numVertex;i++){
            if (matrix[v][i]!=0)   //无向图有向图都适用
                return i;
        }
        return numVertex; //没有则返回numVertex(与后面的地方对应,十分巧妙)
    }

    int next(int v, int w){ //找到v的w邻居的下一个邻居
        for (int i=w+1;i<numVertex;i++){
            if (matrix[v][i]!=0)
                return i;
        }
        return numVertex;
    }

  //真正地实现函数:
    //①:深搜,不得不使用一个帮助函数
    void DFS(){

        for(int i=0;i<numVertex;i++)
            mark[i]=0;
        for(int i=0;i<numVertex;i++)
            if (mark[i]==0) //这一句话!!!
                helpDfs(i,0);
    }

    //②宽搜,可以不需要一个辅助函数:用queue写,就不用递归---不过和书上遍历那里讲得一样,还是辅助一下,所以将其划为私有。
    void BFS(){
        cnt=0;
        queue<int>* q= new queue<int>;
        for(int i=0;i<numVertex;i++)
            mark[i]=0;
        for (int i=0;i<numVertex;i++)  //注意:还是得有这个循环,第一次的时候去掉了:因为只宽搜一个顶点,不一定能全部遍历完所有顶点。---并且这里还是从0开始的
            if(mark[i]==0)    //这一句话!!!
                helpBfs(i,q);
        delete q;
    }

    //单源最小路径
    //需要一个辅助函数:找D中每次未标记的最小值--路径最短的顶点
    void Dijkstra(int s){
        //初始准备
        for (int i=0;i<numVertex;i++)
            mark[i]=0;      //这个不是记录是否访问过,而是记录其的值是否固定,是否已经找到最小值了。
        int D[numVertex];
        int pre[numVertex]; //记录路径,初始化不能达到为-1;
        memset(pre,-1,sizeof (pre));
        //pre[s]=-1;可要可不要,初始结点是知道的
        for (int i=0;i<numVertex;i++)
            D[i]=INFINITY;
        D[s]=0;

        //开始操作
        for (int i=0;i<numVertex;i++){   //最先是从s开始,D[s]=0;一共确定numVertex次,每次确定一个最小
            int min = minVertex(D);
            if (min==-1) return; //说明剩下的点都无法到达,直接结束
            //找到了,那么剩下的值随着更新
            mark[min]=1; //固定这个值
            for (int i=first(min);i<numVertex;i=next(min,i)){
                if (mark[i]==0 && D[i]>D[min]+matrix[min][i]){    //对于标记了的这一条一定不成立,所以可以不用交未标记那句话
                    D[i]=D[min]+matrix[min][i];
                    pre[i]=min;
                }
            }
        }

        //D,pre记录了最小路径的值,和路径
        //输出--只写s=1输出的情况:所以就从i=1遍历即可,若是其他,则还要看输出的顺序
        for (int i=1;i<numVertex;i++){
            if(D[i]==INFINITY) cout<<0+1<<" "<<i+1<<0<<endl;
            else{
                cout << 0+1<<" ";
                string s="";
                int x = i;
                while (pre[x]!=-1){
                    s=std::to_string(x+1)+" "+s;  //输出+1
                    x = pre[x];
                }

                cout<<s<<D[i]<<endl;
            }
        }

    }

    //最小生成树---这种算法出来边不是从大到小的顺序,是随机的
    //另外一个最小生成树算法Kruskal:还要在弄一个辅助函数add和pre来添加边,可能最先的setEdge需要用struct node存一下来选,但是这个算法找到就可以输出,不用像上一个一样排序。
    void Prim(){
        for(int i=0;i<numVertex;i++)
            mark[i]=0;
        int D[numVertex];
        for (int i=0;i<numVertex;i++)
            D[i]=INFINITY;
        D[0]=0; //随便选一个起始点
        //记录被选的边 更新后不一定是最小的,可能有多次更新,所以就不能用cnt直接存,应该对应每一个点。
        struct e E[numVertex];
        E[0].s=0;E[0].e=0;E[0].w=INFINITY;//不输出,使其在最后
        //cnt = 0;

        //开始操作
        for (int i=0;i<numVertex;i++){       //执行numVertex,每个顶点都看一遍,选出MST
            int min = minVertex(D);
            if (min==-1)  return; //不存在最小生成树
            mark[min]=1;   //mark用于是否被选上,就是将原来的点分为了两个集合
            for (int i=first(min);i<numVertex;i=next(min,i))
                if (mark[i]==0 && D[i]>matrix[min][i]){
                    D[i]=matrix[min][i];   //更新后不一定是最小的,可能有多次更新,所以就不能直接存。
                    //E[cnt].s = min;E[cnt].e=i;E[cnt].w=matrix[min][i];
                    E[i].s=min;E[i].e=i;E[i].w=matrix[min][i];
                }
        }

        //输出
        sort(E,E+numVertex,cmp);
        for (int i=0;i<numVertex-1;i++) //不输出最后一条,起始点的
            if (E[i].s<E[i].e) //输出顺序
                cout<<E[i].s+1<<" "<<E[i].e+1<<" "<<E[i].w<<endl;  //输出+1
            else
                cout<<E[i].e+1<<" "<<E[i].s+1<<" "<<E[i].w<<endl;  //输出+1


    }

    //判断有无环存在,无向图 ---用并查集来判断的话,MST最好就写Kruskal了
    bool hasCircle(){
        father = new int[numVertex];
        for (int i=0;i<numVertex;i++)
            father[i]=-1;

        for (int i=0;i<numVertex;i++)
            for (int j=i;j<numVertex;j++){ //无向图遍历可以只遍历一半
                if (matrix[i][j]!=0){
                    int y1 = find(i);
                    int y2 = find(j);
                    if (y1==y2) return true; //同根了,但是现在又要添加一边,一定有一个回路
                    else father[y1]=y2; //不同根,则连接起来
                }
            }
        return false;
        delete[] father;
    }



private:
    int find(int v){
        if (father[v]==-1) return v;
        return father[v]=find(father[v]);  //顺带压缩
    }



    //对应struct e的排序--cmp必须static
    bool static cmp(struct e e1,struct e e2){
        return e1.w<e2.w;
    }


    int minVertex(int *D){
        int minCost=INFINITY;
        int flag=-1;
        for (int i=0;i<numVertex;i++){
            if (minCost>D[i] && mark[i]==0){
                minCost=D[i];
                flag=i;
            }
        }
        return flag;
    }

    void helpDfs(int v, int cnt){
        //Previsit(v)操作------因为本文实现的是从1开始,输出都加1,  再加上控制最后不输出空格:①可以像写的那样做 ②还可以额外增加一个私有变量cnt,每次令其=0--看BFS
        if(cnt!=numVertex-1) {cout<<v+1<<" ";cnt+=1;}
        else cout<<v+1<<endl;

        mark[v]=1;
        for (int i = first(v); i<numVertex;i=next(v,i)){
            if (mark[i]==0)
                helpDfs(i,cnt);
        }
    }
    void helpBfs(int v, queue<int>* q){
        q->push(v);
        mark[v]=1;
        while (!q->empty()) {
            int a = q->front();
            q->pop();

            //Previsit(a)
            if (cnt!=numVertex-1) {cout<<a+1<<" ";cnt+=1;}
            else cout<<a+1<<endl;
            //mark[v]=1; //就在这里设置标记就可以,这里会访问到所有结点,或是像书上那样在两处---------不可以,只能在两处!!!因为这里只会pop出来的时候标记,而后面的没有pop出来的没有标记,在遍历邻居时,又会把它加一遍

            for(int i=first(a);i<numVertex;i=next(a,i))
                if (mark[i]==0){
                    q->push(i);
                    mark[i]=1;
                    }

        }
    }


};


int main(){
    int n,m;
    cin>>n>>m;
    Graphm g(n);

    int s,e,w;
    for (int i=0;i<m;i++){
        cin>>s>>e>>w;
        g.setEdge(s-1,e-1,w); //因为里面全是从0开始
    }
    //cout<<"------";
    g.BFS();
    g.DFS();
    g.Dijkstra(1-1);
    g.Prim();
   bool a = g.hasCircle();
   if (a) cout<<"YES"<<endl;
   else cout<<"NO"<<endl;
}

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值