题意:
给一个无向图,输出它字典序最小的欧拉路径。
分析:
每次选择编号最小且没有访问过的边进行深搜。
代码:
//poj 1041 //sep9 #include <iostream> #include <vector> #include <algorithm> using namespace std; const int maxN=2000; const int maxM=4000; vector< pair<int,int> > adj[maxN+4]; vector<int> path; int f[maxN]; bool vis[maxN]; void add(int x,int y,int z) { adj[x].push_back(make_pair(z,y)); adj[y].push_back(make_pair(z,x)); } int find(int u) { return f[u]==u?u:f[u]=find(f[u]); } void dfs(int u) { int i; for(i=0;i<adj[u].size();++i){ int e=adj[u][i].first; int v=adj[u][i].second; if(!vis[e]){ vis[e]=true; dfs(v); path.push_back(e); } } } bool solve() { int i,j; for(i=1;i<maxN;++i) f[i]=i; for(i=1;i<maxN;++i) for(j=0;j<adj[i].size();++j){ int u=i,v=adj[i][j].second; int pu=find(u),pv=find(v); if(pu!=pv) f[pu]=pv; } int origin=-1; for(i=1;i<maxN;++i) if(adj[i].size()){ if(adj[i].size()%2==1) return false; if(origin==-1) origin=i; if(find(i)!=find(origin)) return false; sort(adj[i].begin(),adj[i].end()); } path.clear(); memset(vis,false,sizeof(vis)); if(origin!=-1) dfs(origin); reverse(path.begin(),path.end()); return true; } int main() { int i,j,x,y,z,end; end=0; while(1){ scanf("%d%d",&x,&y); if(x==0&&y==0){ if(end==0){ if(solve()==false) printf("Round trip does not exist.\n"); else{ for(i=0;i<path.size();++i) printf("%d ",path[i]); printf("\n"); } for(i=1;i<=maxN;++i) adj[i].clear(); end=1; } else break; } else{ end=0; scanf("%d",&z); add(x,y,z); } } return 0; }
原文地址:http://blog.csdn.net/sepnine/article/details/41991309