题意:
给一个无向图,输出它字典序最小的欧拉路径。
分析:
每次选择编号最小且没有访问过的边进行深搜。
代码:
//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;
}