首页 > 代码库 > poj 1041 John's trip 欧拉回路

poj 1041 John's trip 欧拉回路

题意:

给一个无向图,输出它字典序最小的欧拉路径。

分析:

每次选择编号最小且没有访问过的边进行深搜。

代码:

//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;	
}

poj 1041 John's trip 欧拉回路