欧拉路径的解法见我的另一篇文章:http://www.cnblogs.com/shao0099876/p/7366852.html
算法细节如下:
读入边的数据,用sticktype存储,用vis标记解决输出时候的重复问题
对于每一条边看做无向边,对于每一个顶点,其相邻顶点用next数组标记,因为顶点数少,且出现重边情况,所以用计数方法存储,amount存储顶点的度,vis标记用于判断图的连通性
判断特殊情况后,深搜遍历边,对于当前搜索到的顶点,枚举每一条与之相邻的边,将该边删除,并搜索该边的另一个顶点,如果相邻的边都被遍历过,将该顶点放入队列并回溯。
搜索完成后,先判断一下图的连通性。生成的队列为欧拉路径的逆序,根据序列找到相应的边,判断方向,输出即可
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 struct sticktype 5 { 6 int l; 7 int r; 8 bool vis; 9 }stick[101]; 10 struct pointtype 11 { 12 int amount; 13 int next[7]; 14 bool vis; 15 }point[7]; 16 int tail=0; 17 int queue[201]; 18 void dfs(int p); 19 int main() 20 { 21 int n; 22 cin>>n; 23 for(int i=0;i<=6;i++) 24 { 25 point[i].amount=0; 26 for(int j=0;j<=6;j++) 27 { 28 point[i].next[j]=0; 29 } 30 } 31 for(int i=1;i<=n;i++) 32 { 33 cin>>stick[i].l>>stick[i].r; 34 stick[i].vis=false; 35 point[stick[i].l].vis=false; 36 point[stick[i].r].vis=false; 37 point[stick[i].l].amount++; 38 point[stick[i].l].next[stick[i].r]+=1; 39 point[stick[i].r].amount++; 40 point[stick[i].r].next[stick[i].l]+=1; 41 } 42 int m=0; 43 int res=0; 44 for(int i=0;i<=6;i++) 45 { 46 if(point[i].amount!=0) 47 { 48 m++; 49 if(point[i].amount%2!=0) 50 { 51 res++; 52 } 53 } 54 } 55 if(res!=0&&res!=2) 56 { 57 cout<<"No solution"; 58 return 0; 59 } 60 int begin; 61 if(res==0) 62 { 63 for(int i=0;i<=6;i++) 64 { 65 if(point[i].amount!=0) 66 { 67 begin=i; 68 break; 69 } 70 } 71 } 72 else 73 { 74 for(int i=0;i<=6;i++) 75 { 76 if(point[i].amount%2!=0) 77 { 78 begin=i; 79 break; 80 } 81 } 82 } 83 dfs(begin); 84 for(int i=0;i<=6;i++) 85 { 86 if(!point[i].vis&&point[i].amount!=0) 87 { 88 cout<<"No solution"; 89 return 0; 90 } 91 } 92 for(int i=tail;i>=2;i--) 93 { 94 for(int j=1;j<=n;j++) 95 { 96 if(!stick[j].vis) 97 { 98 if(stick[j].l==queue[i-1]&&stick[j].r==queue[i]) 99 { 100 stick[j].vis=true; 101 cout<<j<<" -"<<endl; 102 break; 103 } 104 if(stick[j].r==queue[i-1]&&stick[j].l==queue[i]) 105 { 106 stick[j].vis=true; 107 cout<<j<<" +"<<endl; 108 break; 109 } 110 } 111 } 112 } 113 return 0; 114 } 115 bool check(int p) 116 { 117 for(int i=0;i<=6;i++) 118 { 119 if(point[p].next[i]) 120 { 121 return false; 122 } 123 } 124 return true; 125 } 126 void dfs(int p) 127 { 128 point[p].vis=true; 129 for(int i=0;i<=6;i++) 130 { 131 while(point[p].next[i]) 132 { 133 point[p].next[i]--; 134 int next_point=i; 135 point[next_point].next[p]--; 136 dfs(next_point); 137 } 138 } 139 if(check(p)) 140 { 141 tail++; 142 queue[tail]=p; 143 } 144 return; 145 }
时间: 2024-10-05 04:09:42