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 }