Poj 1041 John’s trip
就是无向图中欧拉回路的求法
首先判断是否存在欧拉回路 判断图的连通性利用并查集实现 然互判断每个点的度数是否为偶数 如果判断存在欧拉回路则利用dfs打印出欧拉回路
#include <iostream>
#include <algorithm>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
const int nmax=100;
const int mmax=2000;
int fa[nmax];//并查集
int vis[mmax];//边的访问数组
vector <pair<int,int>> g[nmax];//连接表
int du[nmax];
int q[nmax];
int top;
void init()
{
for(int i=0;i<nmax;i++)//初始化并查集 清空链接表 清空度
{
fa[i]=i;
g[i].clear();
du[i]=0;
}
memset(vis,0,sizeof(vis));//初始化边的访问数组
top=0;
}
int findfa(int x){if(fa[x]==x)return x;else return fa[x]=findfa(fa[x]);}//并查集搜索函数
void merge(int a,int b)//检查a和b是否属于同一个并查集 不属于的话合并他们
{
int x,y;
x=findfa(a);
y=findfa(b);
if(x!=y)
fa[a]=b;
}
bool judge()//判断是否含有欧拉回路
{
int root=findfa(1);
for(int i=1;i<nmax;i++)//检查图的连同性和每个节点的度是否为偶数
{
if(du[i]&&(root!=findfa(i)))
return false;
if(du[i]&&(du[i]&1))
return false;
}
return true;
}
bool cmp(pair<int ,int> a,pair<int ,int > b)
{
return a.second<b.second;
}
void mysort()
{
for(int i=1;i<nmax;i++)
{
if(du[i])
{
sort(g[i].begin(),g[i].end(),cmp);
}
}
}
void dfs(int s)
{
for(int i=0;i<g[s].size();i++)
{
if(!vis[g[s][i].second])
{
vis[g[s][i].second]=1;
q[top++]=g[s][i].second;//存储边
dfs(g[s][i].first);
}
}
}
void output()
{
for(int i=0;i<top;i++)
{
if(i!=top-1)printf("%d ",q[i]);
else printf("%d\n",q[i]);
}
}
int main(int argc,char *argv[])
{
int a,b,z,start;
while(scanf("%d %d",&a,&b)!=EOF)
{
init();//初始化并查集 边访问数组 清空度 连接表
if(a==0&&b==0)break;
scanf("%d",&z);
start=min(a,b);
g[a].push_back(make_pair(b,z));
g[b].push_back(make_pair(a,z));
du[a]++;
du[b]++;
merge(a,b);//ab合并成同一个并查集
while(scanf("%d %d",&a,&b)!=EOF)
{
if(a==0&&b==0)break;
scanf("%d",&z);
g[a].push_back(make_pair(b,z));
g[b].push_back(make_pair(a,z));
du[a]++;
du[b]++;
merge(a,b);
}
if(judge())
{
mysort();
dfs(start);
output();
}
else
printf("Round trip does not exist.\n");
}
return 0;
}