Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 5950 | Accepted: 1946 | Special Judge |
Description
Input
Output
Sample Input
1 2 1 2 3 2 3 1 6 1 2 5 2 3 3 3 1 4 0 0 1 2 1 2 3 2 1 3 3 2 4 4 0 0 0 0
Sample Output
<span style="font-size: 14px;">1 2 3 5 4 6 </span><p style="font-size: 14px;">Round trip does not exist.</p><p style="font-size: 14px;"> </p><p><strong><span style="font-size:18px;">此题目从半上午做到这时候,首先把算法弄懂了,然后就是找bug将近三个小时!!bug?判断相等的时候要用两个等号 活生生少写一个!!!!醉了~。核心思想是在判断完有欧拉回路的情况下,这个可以从所有点度数都是偶数的充分条件来判定,然后从标号最小的边开始dfs,因为程序里有个对邻接表排序的过程你,那么必然之后沿着边的标号上升的dfs过程。遇到走不通就回溯,那么此时必然还要存在环,否则不会出现走不通,那时应该全图是一个环才对。遇到最小序环(假设存在)且无法继续dfs回溯的时候,回溯出来的那条边必然到最后是欧拉回路最后一条边,直接push,否则就会出现沿着欧拉回路走的时候“过快”的回到原点了。遇到最小序环且无法走通的情况下,此时就要从最小序环遍历各点dfs并按照边标号上升的顺序深搜其他环,那么path里面到最后就保存的是欧拉路径的 逆序,reverse一下就么么哒了~</span></strong></p><p style="font-size: 14px;"><pre name="code" class="cpp">#include<iostream> #include<sstream> #include<algorithm> #include<cstdio> #include<string.h> #include<cctype> #include<string> #include<cmath> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; //input: adj 全局变量,adj【i】表示从结点i连出的所有边 //判断是否有解。有向无向皆可,path(全局)保存欧拉回路。 const int maxn=2000; const int maxm=1000000; int father[maxn]; vector< pair<int,int > > adj[maxn]; bool vis[maxm]; int getFather(int x) { return x==father[x]?x:father[x]=getFather(father[x]); // int root=a; // int temp; // while(father[root]!=root) // root=father[root]; // while(father[a]!=root) // { // temp=a; // a=father[a]; // father[temp]=root; // } } void add (int x,int y,int z) { adj[x].push_back(make_pair(z,y)); adj[y].push_back(make_pair(z,x)); } vector<int >path; void dfs(int u) { for(int it=0; it<adj[u].size(); it++) if(!vis[adj[u][it].first]) { vis[adj[u][it].first]=1; dfs(adj[u][it].second); path.push_back(adj[u][it].first); } } bool solve() { for(int i=0; i<maxn; i++) father[i]=i; for(int i=0; i<maxn; i++) { for(int j =0; j < adj[i].size() ; ++j) { father[getFather(i)]=getFather(adj[i][j].second); } } int origin=-1; for(int i=0; i<maxn; i++) if(adj[i].size()) { if(adj[i].size()%2==1)return 0; if(origin==-1)origin=i; if(getFather(i)!=getFather(origin))return 0; sort(adj[i].begin(),adj[i].end()); } path.clear(); memset(vis,0,sizeof(vis)); if(origin!=-1)dfs(origin); reverse(path.begin(),path.end()); return 1; } int main() { int x,y,z; while(scanf("%d%d",&x,&y)!=EOF) { if(x==0&&y==0) break; scanf("%d",&z); for(int i=0; i<maxn; i++) adj[i].clear(); add(x,y,z); while(scanf("%d%d",&x,&y)!=EOF) { if(y==0&&x==0) break; scanf("%d",&z); add(x,y,z); } if(solve()) { int i; for( i=0; i<path.size()-1; i++) printf("%d ",path[i]); printf("%d\n",path[i]); } else printf("Round trip does not exist.\n"); } return 0; }
poj1041 John's trip (无向图求欧拉回路方案)
原文地址:http://blog.csdn.net/lsgqjh/article/details/46635025