链式前向星

大憨熊 提交于 2019-11-29 10:11:56
 1 #include <iostream>
 2 #define n 3000    //总节点数
 3 #define m 6000  //总边数 
 4 using namespace std;
 5 int cnt=1;        //计数器,用于标记边的序号,以及记录边数 
 6 int head[n];    //指向当前起点的最末边序号](反向遍历时将其称为初边,即反向遍历时最先遍历的边) 
 7 int vis[m];
 8 struct edge{
 9     int to;        //指向当前序号边的终点 
10     int next;    //指向当前序号边的后继边序号(两条边的起点相同,即某节点的两条出度) 
11     int w;        //存储边的权值
12 }e[m];
13 
14 void add(int u,int v,int w){    //加边函数 
15     e[cnt].to=v;                //存储该边终点 
16     e[cnt].next=head[u];        //因为节点u出度增加,所以head[u]成为新边的上一条边(由于遍历时反向遍历,所以使用next而非last命名) 
17     head[u]=cnt++;                 //由于加入新边,故cnt++,此时head[u]的最末边指向最新的cnt 
18     e[cnt].w=w;                    //存储该边权值 
19 } 
20 
21 void reduce(int u,int v){        //删边函数 
22     for(int i=head[u];i;i--)    //定义i为u-->v的边的序号,通过for搜索序号i 
23     {
24         if(e[i].to==v)        //若e[i].to==v,说明找到序号i 
25         {
26             e[i].to=u;        //将边的终点改为边的起点,以达到删边的目的 
27             return;            //跳出for,返回 
28         }    
29     }
30 } 
31 
32 void bfs(int u){    //遍历时反向遍历,head[]由末边成为初边 
33     for(int i=head[u];i;i=e[i].next)    //初始化i记录u点的初边;若i存在;i记录u点的后继边                
34     {
35         printf("%d-->%d\n",u,e[i].to);
36     }
37 } 
38 
39 void dfs(int u){    //dfs=bfs(bfs) 
40     vis[u]=1;                        //vis[]记录节点是否被访问 
41     for(int i=head[u];i;i=e[i].next)
42     {
43         if(!vis[e[i].to])            //若未被访问,则work,并从该点继续dfs 
44         {
45             printf("%d-->%d\n",u,e[i].to);
46             dfs(e[i].to);
47         }
48     }
49 }
50 
51 int main(){
52     add(1,2,1);
53     add(1,3,1);
54     add(1,4,1);
55     add(3,9,1);
56     add(3,8,1);
57     add(4,5,1);
58     add(4,6,1);
59     add(4,7,1);    
60     reduce(1,4);
61     bfs(1);
62     cout<<endl;
63     dfs(1);
64     return 0;
65 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!