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 }