Problem E Wormhouse题解

Posted 桂月二四

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Problem E Wormhouse题解相关的知识,希望对你有一定的参考价值。

题意:给定一个欧拉回路(即经过所有边的一条回路),计算另一条欧拉回路,要求这条回路的字典序要大于给定的回路。
字母m的含义:边数,所以要读入m+1个数(每两个数字之间组成一条回路)

思路:dfs就完事了。
下面是我在oj’上提交的代码,debug的时候一顿乱改,加了很多冗杂的东西。。
提几点:(不想看的话请移步文章末尾
1.代码采用邻接矩阵(mp)存图(因为n不大)
2.check用来检查最后生成的路径是否与原来一致,如果一致则要舍弃
3.如果去掉okk这一个东西,那么这个代码可以求出所有符合题意的路径,但是只要求一个,所以加了okk这一个判断
4.函数的第三个参数flag用来判断是否已经字典序大于原来的了,如果flag为1,那么任何的符合条件的i均可以加入新路径,否则只能是大于等于原来路径的i

#include <bits/stdc++.h>
#define ll long long 
#define INF 0x3f3f3f3f
using namespace std;
int b[2010];
int mp[101][101];
int a[2010];
int vis[101][101];
int n,m;
int okk;
int check()

	for(int i=1;i<=m;i++)
		if(a[i]!=b[i]) return 1;
	return 0;

void dfs(int u,int k,int flag)
	
	a[k] = u;
	if(!okk&&k==m&&u==b[0]&&check())
	
		for(int i=0;i<=m;i++)
			cout<<a[i]<<" ";
		okk = 1;
	
	//u的邻接点
	if(!okk)
	for(int i=1;i<=n;i++)
	
		if(!vis[i][u]&&mp[i][u])
		
			if(flag||b[k+1]<i)
			
				vis[u][i]=vis[i][u]=1;
				 dfs(i,k+1,1);
				vis[u][i]=vis[i][u]=0;
			
			else if(b[k+1]==i)
			
				vis[u][i]=vis[i][u]=1;
				 dfs(i,k+1,0);
				vis[u][i]=vis[i][u]=0;
			
		
	  

int main()

	cin>>n>>m;
	cin>>b[0];
	for(int i=1;i<=m;i++)
	
		cin>>b[i];
		mp[b[i]][b[i-1]] = mp[b[i-1]][b[i]] = 1;
	
	a[0] = 1;
	dfs(b[0],0,0);
	if(!okk) cout<<"No solution" ;
    return 0;

这代码写的很乱,很乱。
看不懂请看
https://blog.csdn.net/cyendra/article/details/8726525

这个题解给出了比我好的代码以及优化方式。

以上是关于Problem E Wormhouse题解的主要内容,如果未能解决你的问题,请参考以下文章

uoj117:欧拉回路——题解

UVa 10735 - Euler Circuit(最大流 + 欧拉回路)

BZOJ1023:[SHOI2008]仙人掌图——题解

URAL1519:Formula 1——题解

[CF788B]Weird journey_欧拉回路

UOJ#3白鸽