图论问题(2):欧拉回路

版权声明:代码原创,如需转载,请发邮箱至[email protected][email protected],或qq3145743347. https://blog.csdn.net/ebirth/article/details/91354290

图论问题概述总结(2)

对于图论,我们尊熟悉的算法是比较多的,这次,我就找了集中常用的算法。

  1. 欧拉回路

欧拉回路就是在一张有向或无向图中求出一笔画问题的具体画法
方法:

  • 先思考此题是否是用欧拉回路来解决。
  • 思考是有向图或无向图来解决适用于欧拉回路。
  • 对于有向图,保证每个点的入度为出度;对于系数图,保证每个点为偶数。

我们对于这个算法,可以用来图:

就向这样,接下来,我们看看代码:
题:http://120.77.248.79/problem/3023105

#include<bits/stdc++.h>
using namespace std;
const int maxn=200000;
const int maxm=200000;
struct node{
	int v,next;
	int len;
}e[maxm];
int g[maxn],ans;
void init(){
	memset(g,-1,sizeof(g));
	ans=0;
}
void add(int u,int v){
	e[ans].v=v;
	e[ans].next=g[u];
	g[u]=ans++;
}
int n,m;
int degree[maxn];
int cnt;
bool vis[maxn];
void dfs(int u){
	vis[u]=true;
	cnt++;
	for (int i=g[u];i!=-1;i=e[i].next){
		int v=e[i].v;
		if (!vis[v]){
			dfs(v);
		}
	}
}
void euler(){
	dfs(1);
	if(cnt!=n){
		cout<<0<<endl;
		return;
	}
	int tot=0;
	for(int i=1;i<=n;i++){
		if(degree[i]%2==1){
			tot++;
		}
	}
	if(tot==0){
		cout<<"1"<<endl;
	}else{
		cout<<"0"<<endl;
	}
}
int main(){
	init();
	memset(degree,0,sizeof(degree));
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int u,v;
		cin>>u>>v;
		add(u,v);
		add(v,u);
		degree[u]++;
		degree[v]++;
	}
	euler();
	return 0;
}

这就是题欧拉回路的做法,这是他的基本思维,接下来,我们看看一道题:https://www.luogu.org/problemnew/show/P2731
代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int g[1010][1010];
int a[100000],b[100000];
int ans;
int s=1000000,q=1000000;
void add(int x){
	for(int i=1;i<=500;i++){
		if(g[x][i]){
			g[x][i]--;
			g[i][x]--;
			add(i);
		}
	}
	b[ans--]=x;
}
int main(){
	cin>>n;
	ans=n+1;
	for(int i=1;i<=n;i++){
		int u,v;
		cin>>u>>v;
		g[u][v]++;
		g[v][u]++;
		a[u]++;
		a[v]++;
		s=min(s,min(u,v));
	}
	for(int i=1;i<=500;i++){
		if(a[i]%2==1){
			q=min(i,q);
		}
		if(q<1000000){
			add(q);
		}else{
			add(s);
		}
	}
	for(int i=1;i<=n+1;i++){
		cout<<b[i]<<endl;
	}
	return 0;
} 

同理,于欧拉回路的思路是一样的。
下期见,下棋(拓普排序)
这期完毕,下棋在讲。

猜你喜欢

转载自blog.csdn.net/ebirth/article/details/91354290
今日推荐