poj1041 John's trip(欧拉回路+输出路径)
题意:一个无向图,问图中是否存在欧拉回路,如果存在,则输出字典序最小的那条欧拉回路(输入按序走过的所有边标号)。且题目中保证了该无向图是连通的。思路:欧拉路径的输出方式可以参考刘汝佳入门经典P112中的代码。不过那里的图中的边是用(i,j)来表示的,而这里的图中的边是用一个数字编号表示的.所以源代码中还需要做点小修改.然后要保证从John的家作为起始点输出欧拉回路且保证字典序最小,因为eule
·
题意:一个无向图,问图中是否存在欧拉回路,如果存在,则输出字典序最小的那条欧拉回路(输入按序走过的所有边标号)。且题目中保证了该无向图是连通的。
思路:欧拉路径的输出方式可以参考刘汝佳入门经典P112中的代码。不过那里的图中的边是用(i,j)来表示的,而这里的图中的边是用一个数字编号表示的.所以源代码中还需要做点小修改.然后要保证从John的家作为起始点输出欧拉回路且保证字典序最小,因为euler这个函数输出的欧拉路径是从起点逆序的,所以我们需要把最后结果保存在数组中,最后逆序输出,且每次都是从小到大选择与当前节点相连的可行边的(这样可以保证输出结果的字典序最小).还需要在用euler之前判断无向连通图的所有节点是不是都是偶数度,如果不是则不存在欧拉回路.
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxm 2000
#define LL long long
int cas=1,T;
const int maxn =100;
struct edge
{
int u,v;
}edges[maxm];
int n,m;
int degree[maxn];
int vis[maxm];
int ans[maxm];
int cnt;
bool check()
{
for (int i = 1;i<=n;i++)
if (degree[i]%2!=0)
return false;
return true;
}
void euler(int s)
{
for (int i = 1;i<=m;i++)
if (!vis[i] && (edges[i].u==s || edges[i].v==s))
{
vis[i]=1;
euler(edges[i].u+edges[i].v-s);
ans[cnt++]=i;
}
}
int main()
{
int x,y,z;
while (scanf("%d%d",&x,&y) && x)
{
cnt=n=m=0;
int jh = min(x,y);
memset(degree,0,sizeof(degree));
memset(vis,0,sizeof(vis));
scanf("%d",&z);
edges[z].u=x;
edges[z].v=y;
degree[x]++;
degree[y]++;
m++;
n=max(n,max(x,y));
while (scanf("%d%d",&x,&y) && x)
{
scanf("%d",&z);
edges[z].u=x;
edges[z].v=y;
degree[x]++;
degree[y]++;
m++;
n=max(n,max(x,y));
}
if (!check())
{
puts("Round trip does not exist.");
continue;
}
euler(jh);
printf("%d",ans[m-1]);
for (int i = m-2;i>=0;i--)
printf(" %d",ans[i]);
printf("\n");
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献2条内容
所有评论(0)