图的广度优先搜索和深度优先搜索


图的广度优先搜索和深度优先搜索

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <queue>  
  3. #include <stdio.h>  
  4. #include <queue>  
  5. #include <stdlib.h>  
  6. #include <list>  
  7. using namespace std;  
  8.   
  9. #define VERTEXNUM 100//最大顶点数  
  10. #define INF  65535  
  11. enum nodecolor {white,gray,black};  
  12. typedef struct node//参见算法导论322  
  13. {  
  14.     int adjvex;//顶点位置  
  15.     struct node *next;//指向下一条边的指针  
  16. }EdgeNode;  
  17. typedef struct vnode  
  18. {  
  19.     char vertex;//顶点信息  
  20.     EdgeNode *firstedge;//指向第一条依附该顶点的边的指针  
  21.     nodecolor color;  
  22.     int d;//广度优先中到第一个点的距离,深度优先中被发现的时间  
  23.     int f;//深度优先中结束检查此结点的邻接表的时间  
  24.     vnode* pi;//父结点  
  25. }AdjList[VERTEXNUM];  
  26. typedef struct  
  27. {  
  28.     AdjList vertexs;//邻接表  
  29.     int vernum,edgenum;//图中当前的顶点和边数  
  30. }Graph;  
  31.   
  32. //建立邻接表  
  33. void MakeGraph(Graph *G)  
  34. {  
  35.     int v1,v2;  
  36.     int i,j,k;  
  37.     cout<<"请输入图的顶点数和边数"<<endl;  
  38.     cin>>G->vernum>>G->edgenum;  
  39.     cout<<"请输入顶点信息(顶点号<CR>)每个顶点以回车作为结束:"<<endl;  
  40.   
  41.     for(i=0;i<G->vernum;++i)  
  42.     {  
  43.         //getchar();  
  44.         cin>>G->vertexs[i].vertex;  
  45.         G->vertexs[i].firstedge=NULL;//初始第一条边为空  
  46.     }  
  47.   
  48.     cout<<"请输入每条边对应的两个顶点的序号(格式为i,j):"<<endl;  
  49.     EdgeNode *p;  
  50.     for(k=0;k<G->edgenum;k++)  
  51.     {  
  52.         cin>>i>>j;//读入边<vi,vj>的序号  
  53.         p=(node*)malloc(sizeof(node));//生成新的结点  
  54.         p->adjvex=j-1;  
  55.         p->next=G->vertexs[i-1].firstedge;  
  56.         G->vertexs[i-1].firstedge=p;//这3行是插入链表的操作  
  57.     }  
  58. }  
  59.   
  60. //广度优先遍历  
  61. void BFS(Graph *G,vnode *s)  
  62. {  
  63.     int i;  
  64.     queue<vnode *> Q;  
  65.     EdgeNode *p;  
  66.     vnode *u;  
  67.     for(i=0;i<G->vernum;i++)  
  68.     {  
  69.         G->vertexs[i].d=INF;  
  70.         G->vertexs[i].pi=NULL;  
  71.         G->vertexs[i].color=white;  
  72.     }  
  73.     s->color=gray;  
  74.     s->d=0;  
  75.     s->pi=NULL;  
  76.     Q.push(s);  
  77.     while(!Q.empty())  
  78.     {  
  79.         u=Q.front();  
  80.         Q.pop();//出队  
  81.         p=u->firstedge;  
  82.         while(p)  
  83.         {  
  84.             if(G->vertexs[p->adjvex].color==white)  
  85.             {  
  86.                 G->vertexs[p->adjvex].color=gray;  
  87.                 G->vertexs[p->adjvex].d=u->d+1;  
  88.                 G->vertexs[p->adjvex].pi=u;  
  89.                 Q.push(&G->vertexs[p->adjvex]);  
  90.             }  
  91.             p=p->next;  
  92.         }  
  93.         u->color=black;  
  94.     }  
  95.     for(i=0;i<G->vernum;i++)   
  96.     {  
  97.         u=&G->vertexs[i];  
  98.         cout<<"结点:"<<u->vertex<<"距离:"<<u->d<<"颜色:"<<u->color<<endl;  
  99.     }          
  100. }  
  101.   
  102. //深度优先遍历  
  103. void DFS_visit(Graph *G,vnode *u);  
  104. int t=0;//时间  
  105. list<vnode*> L;//用于拓扑排序  
  106.   
  107. void DFS(Graph *G)  
  108. {  
  109.     int i;  
  110.     for(i=0;i<G->vernum;i++)  
  111.     {  
  112.         G->vertexs[i].d=INF;  
  113.         G->vertexs[i].pi=NULL;  
  114.         G->vertexs[i].color=white;  
  115.     }  
  116.     for(i=0;i<G->vernum;i++)  
  117.     {  
  118.         if(G->vertexs[i].color==white)  
  119.             DFS_visit(G,&G->vertexs[i]);   
  120.     }  
  121.     for(i=0;i<G->vernum;i++)   
  122.     {  
  123.         vnode *u=&G->vertexs[i];  
  124.         cout<<"结点:"<<u->vertex<<"开始:"<<u->d<<"结束:"<<u->f<<endl;  
  125.     }          
  126. }  
  127. void DFS_visit(Graph *G,vnode *u)  
  128. {  
  129.     EdgeNode *p;  
  130.     u->color=gray;  
  131.     u->d=++t;  
  132.     p=u->firstedge;  
  133.     while(p)  
  134.     {  
  135.        if(G->vertexs[p->adjvex].color==white)  
  136.        {  
  137.            G->vertexs[p->adjvex].pi=u;  
  138.            DFS_visit(G,&G->vertexs[p->adjvex]);  
  139.        }   
  140.        p=p->next;  
  141.     }  
  142.     u->color=black;  
  143.     u->f=++t;  
  144.     L.insert(L.begin(),u);//用于拓扑排序  
  145. }  
  146.       
  147. //拓扑排序  
  148. list<vnode*>& topological_sort(Graph* G)  
  149. {  
  150.     DFS(G);  
  151.     return L;  
  152. }  
  153.   
  154. int main()  
  155. {  
  156.     int j;  
  157.     Graph *G=(Graph *)malloc(sizeof(Graph));  
  158.     MakeGraph(G);  
  159.     cout<<"请输入广度优先开始遍历的结点的序号:"<<endl;  
  160.     cin>>j;  
  161.     cout<<"广度优先遍历:"<<endl;  
  162.     BFS(G,&G->vertexs[j-1]);  
  163.     cout<<"深度优先遍历:"<<endl;  
  164.     DFS(G);  
  165.     return 0;  
  166. }  


最小生成树:

[cpp]  view plain copy
  1. //Kruskal  
  2.   
  3. const int maxint = 999999;  
  4. typedef struct Road  
  5. {  
  6.     int c1,c2;//a到b  
  7.     int value;//权值  
  8. }Road;  
  9.   
  10. int no;  
  11. int line;  
  12. Road road[100];  
  13. int node[101];  
  14.   
  15. bool myCmp(const Road &a,const Road &b)  
  16. {  
  17.     return (a.value<b.value);  
  18. }  
  19.   
  20. int Find_Set(int n)  
  21. {  
  22.     if(node[n]==-1)  
  23.         return n;  
  24.     else  
  25.         return Find_Set(node[n]);//其实就是沿着树找到根  
  26. }  
  27.   
  28. bool Merge(int s1,int s2)  
  29. {  
  30.     int r1=Find_Set(s1);  
  31.     int r2=Find_Set(s2);  
  32.     if(r1==r2)//根相同就是属于同一棵树  
  33.         return 0;  
  34.     if(r1<r2)  
  35.         node[r2]=r1;  
  36.     else  
  37.         node[r1]=r2;  
  38.     return 1;  
  39. }  
  40.   
  41. int main()  
  42. {  
  43.     freopen("input.txt","r",stdin);  
  44.     memset(node,-1,sizeof(node));  
  45.     cout<<"Input the number of the node:";  
  46.     cin>>no;  
  47.     cout<<"Input the number of the line:";  
  48.     cin>>line;  
  49.     cout<<"Input the edge:";  
  50.     for(int i=0;i<line;++i)  
  51.     {  
  52.         cin>>road[i].c1>>road[i].c2>>road[i].value;  
  53.     }  
  54.     sort(road,road+line,myCmp);  
  55.     int sum=0,count=0;  
  56.     for(int i=0;i<line;++i)  
  57.     {  
  58.         if(Merge(road[i].c1,road[i].c2))  
  59.         {  
  60.             count++;  
  61.             sum+=road[i].value;  
  62.         }  
  63.         if(count==no-1)  
  64.             break;  
  65.     }  
  66.     cout<<sum<<endl;  
  67. }  
  68.   
  69. //Prim  
  70.   
  71. const int INF=1001;  
  72. int no,line;  
  73. int arcs[101][101];  
  74. int dis[101],vis[101];  
  75. int _min;  
  76.   
  77. int main()  
  78. {  
  79.     freopen("input.txt","r",stdin);  
  80.   
  81.     cout<<"Input the number of the node:";  
  82.     cin>>no;  
  83.     cout<<"Input the number of the line:";  
  84.     cin>>line;  
  85.   
  86.     for(int i=0;i<no;++i)  
  87.         for(int j=0;j<no;++j)  
  88.             arcs[i][j]=INF;  
  89.     cout<<"Input the edge:";  
  90.     int p,q,len;//输入p,q两点及路径长度  
  91.     for(int i=0;i<line;++i)  
  92.     {  
  93.         cin>>p>>q>>len;  
  94.         if(len<arcs[p-1][q-1])//有重边  
  95.         {  
  96.             arcs[p-1][q-1]=len;  
  97.             arcs[p-1][q-1]=len;//表示无向图  
  98.         }  
  99.     }  
  100.     memset(vis,0,sizeof(vis));  
  101.     for(int i=1;i<no;++i)  
  102.         dis[i]=arcs[0][i];  
  103.     vis[0]=1;  
  104.     int sum=0,rec=0;  
  105.     dis[0]=0;  
  106.     for(int i=1;i<no;++i)  
  107.     {  
  108.         _min=INF;  
  109.         for(int j=0;j<no;++j)  
  110.             if(!vis[j]&&dis[j]<_min)  
  111.             {  
  112.                 rec=j;  
  113.                 _min=dis[j];  
  114.             }  
  115.         cout<<"min:"<<_min<<endl;  
  116.         sum+=_min;  
  117.         vis[rec]=1;  
  118.         for(int j=0;j<no;++j)  
  119.             if(!vis[j]&&arcs[rec][j]<dis[j])  
  120.                 dis[j]=arcs[rec][j];  
  121.     }  
  122.     printf("%d\n",sum);  
  123.     return 0;  
  124. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值