题目:http://poj.org/problem?id=1041
求字典序欧拉回路;
首先,如果图是欧拉图,就一定存在欧拉回路,直接 dfs 即可,不用 return 判断什么的,否则TLE...
所以还是模板比较好啊;
字典序有点麻烦,一开始我用优先队列啦各种各样的超级麻烦,但是其实先存下读进来的边,一边放进优先队列里排序,然后倒着连上,那么它就会正着遍历了;
网上的 TJ 都是存进二维数组里桶排,也还行吧,但总感觉不够优秀啊,时间和空间都;
得到了字典序加边的方法!

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,st,deg[50],ans[2000],top,tot,map[50][2000];//ans不是20!!! bool vis[2000]; void print() { for(int i=top;i;i--)printf("%d ",ans[i]); printf(" "); } void insert(int x,int y,int z) { map[x][z]=y; map[y][z]=x; tot++; deg[x]++; deg[y]++; n=max(n,(max(x,y))); } void dfs(int x) { for(int i=1;i<=tot;i++) { if(vis[i]||!map[x][i])continue; vis[i]=1; dfs(map[x][i]); ans[++top]=i; } } int main() { int x,y,z; while(1) { scanf("%d%d",&x,&y); if(!x&&!y)return 0; memset(map,0,sizeof map); memset(deg,0,sizeof deg); memset(vis,0,sizeof vis); top=0; n=0; tot=0; scanf("%d",&z); st=min(x,y);// insert(x,y,z); while(1) { scanf("%d%d",&x,&y); if(!x&&!y)break; scanf("%d",&z); insert(x,y,z); } bool fl=0; for(int i=1;i<=n;i++) if(deg[i]%2){printf("Round trip does not exist. "); fl=1; break;} if(fl)continue; dfs(st); print(); } }
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; int n,m,st,hd[50],ct=1,deg[50],ans[2000],top,tot; bool vis[4000]; struct N{ int to,nxt,bh; N(int t=0,int n=0,int b=0):to(t),nxt(n),bh(b) {} }ed[4000]; priority_queue<pair<int,int> >q[50]; void insert(int x,int y,int z) { q[x].push(make_pair(z,y)); q[y].push(make_pair(z,x)); tot++; deg[x]++; deg[y]++; n=max(n,(max(x,y))); } void add() { for(int i=1;i<=n;i++) while(q[i].size()) { int bh=q[i].top().first,to=q[i].top().second; q[i].pop(); ed[++ct]=N(to,hd[i],bh); hd[i]=ct; } } void print() { for(int i=top;i;i--)printf("%d ",ans[i]); printf(" "); } //bool dfs(int x) //{ // if(top==tot){print(); return 1;} // int t=0; // for(int i=hd[x];i;i=ed[i].nxt) // { // if(vis[ed[i].bh])continue; // ans[++top]=ed[i].bh; vis[ed[i].bh]=1; // if(dfs(ed[i].to))return 1; // top--; vis[ed[i].bh]=0; // } // return 0; //} void dfs(int x) { for(int i=hd[x];i;i=ed[i].nxt) { if(vis[ed[i].bh])continue; vis[ed[i].bh]=1; dfs(ed[i].to); ans[++top]=ed[i].bh; } } int main() { int x,y,z; while(1) { scanf("%d%d",&x,&y); if(!x&&!y)return 0; ct=1; top=0; tot=0; memset(hd,0,sizeof hd); memset(vis,0,sizeof vis); memset(deg,0,sizeof deg); for(int i=1;i<=44;i++) while(q[i].size())q[i].pop(); scanf("%d",&z); st=x; insert(x,y,z); while(1) { scanf("%d%d",&x,&y); if(!x&&!y)break; scanf("%d",&z); insert(x,y,z); } add(); bool fl=0; for(int i=1;i<=n;i++) if(deg[i]%2){printf("Round trip does not exist. "); fl=1; break;} if(fl)continue; dfs(st); print(); // if(!dfs(st))printf("Round trip does not exist. "); } }