关于为什么不选桥
因为选桥之后会变成两个联通分支,这时由于可能产生的新联通分支不是孤立顶点,他俩都不联通了,那么也就绝对不可能“一笔画”走下来了
关于为什么可以选除桥之外的任意一条边走
本质原因是因为环与环嵌套后这俩环是没有内外之分的,所以说你任意选一条边本质是选择在哪个环上走,而你走任何一个环最后都是回到出发点,所以就随便走
其实欧拉图就是环套环或者环套环套环或者环套环套环套环或者...的图
#include<bits/stdc++.h> using namespace std; int mtx[200][200]; int deg[200]; bool vis[200]; bool dfs(int u,int v){ vis[u]=1; if(u==v) return 1; for(int i=0;i<200;i++){ if(mtx[u][i]&&!vis[i]){ if(dfs(i,v)) return 1; } } return 0; } bool not_bridge(int u,int v){ //判桥用dfs判的 memset(vis,0,sizeof(vis)); mtx[u][v]=mtx[v][u]=0; int x=0; for(int i=0;i<200;i++){ if(mtx[u][i]) x++; } if(!x) return 1; for(int i=0;i<200;i++){ if(mtx[u][i]){ if(dfs(i,v)){ mtx[u][v]=mtx[v][u]=1; return 1; } } } mtx[u][v]=mtx[v][u]=1; return 0; } int fa[200]; int getfa(int x){ //并查集判一下是不是只有一个连通分量 while(x!=fa[x]) x=fa[x]; return x; } void joint(int u,int v){ fa[getfa(v)]=getfa(u); } int main(){ int n; cin>>n; char t[4]; int minch='z'+1-'A'; for(int i=0;i<=200;i++) fa[i]=i; for(int i=1;i<=n;i++){ cin>>t; int u=t[0]-'A'; minch=min(minch,u); int v=t[1]-'A'; minch=min(minch,v); if(getfa(u)!=getfa(v)) joint(u,v); mtx[u][v]=1; deg[u]++; mtx[v][u]=1; deg[v]++; } int prefa=-1; for(int i=0;i<=200;i++){ if(deg[i]){ if(prefa==-1) prefa=getfa(i); else{ if(prefa!=getfa(i)){ puts("No Solution"); return 0; } } } } int odd=0; for(int i=0;i<200;i++){ if(deg[i]%2){ odd++; } if(odd>2){ puts("No Solution"); return 0; } } if(odd==2){ minch='z'+1-'A'; for(int i=0;i<200;i++){ if(deg[i]%2){ minch=min(minch,i); } } } queue<int> Q; Q.push(minch); while(!Q.empty()){ int temp=Q.front(); Q.pop(); cout<<(char)(temp+'A'); for(int i=0;i<200;i++){ if(mtx[temp][i]&¬_bridge(temp,i)){ mtx[temp][i]=mtx[i][temp]=0; Q.push(i); break; } } } return 0; } //后来我学了hierholzer,强烈建议大家去学这个算法啊,实用多了