文章目录
欧拉回路的判定
1无向图
无向图:连通(不考虑度为 0 的点),每个顶点度数都为偶数。
hdu 1878
ac代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int MAXN = 3 * 100000 + 7;
const int INF = 0x7f7f7f7f;
/***************************
无向欧拉图的判断
***************************/
int d[1005],father[1005];
void init(int n)
{
memset(d, 0,sizeof d);
for(int i = 1; i <= n; i++) father[i] = i;
}
int getfa(int x)
{
while(x != father[x]) x = father[x];
return x;
}
int main()
{
std::ios::sync_with_stdio(false);
int n,m;
while(cin>>n>>m){
init(n);
int sum = n;
while(m--){
int u,v;
cin>>u>>v;
d[u]++ , d[v]++;
int x = getfa(u), y = getfa(v);
if(x != y) father[x] = y , sum--;
}
//如果图不联通
if(sum > 1){
cout<<0<<endl;
continue;
}
bool flag = true;
for(int i = 1; i <= n; i++){
if(d[i] % 2){
flag = false;
cout<<0<<endl;
break;
}
}
if(flag) cout<<1<<endl;
}
return 0;
}
2 有向图
欧拉路径存在的充要条件:
1.有向图存在欧拉回路的充要条件 所有顶点的 入度 和 出度 的和是 偶数,且该图是连通图(并查集)。
2.有向图含有欧拉通路的充要条件
起始点s 的入度=出度-1,结束点t的出度=入度-1 或两个点的入度=出度,且该图是连通图(并查集)。
题意:
给你多个单词,问你能不能将所有单词组成这样一个序列:序列的前一个单词的尾字母与后一个单词的头字母相同.
把每个单词的首尾字符当作点,这个字符就是这两个点连出的一条边,也就是求有向图的欧拉路径
poj 1386
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
using namespace std;
const int MAXN = 3 * 100000 + 7;
const int INF = 0x7f7f7f7f;
/***************************
有向欧拉图的判断
***************************/
int in[30],out[30],father[30];
bool exist[30];
void init()
{
memset(out, 0 ,sizeof out);
memset(in, 0,sizeof in);
memset(exist , false , sizeof exist);
for(int i = 0; i < 30; i++) father[i] = i;
}
int getfa(int x)
{
while(x != father[x]) x = father[x];
return x;
}
void marge(int x, int y)
{
x = getfa(x) , y = getfa(y);
if( x != y) father[x] = y;
}
int main()
{
//std::ios::sync_with_stdio(false);
int t;
char str[1005];
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
init();
for(int i = 0; i < n; i++){
scanf("%s",str);
int len = strlen(str);
int u = str[0] - 'a';
int v = str[len - 1] - 'a';
out[u]++ , in[v]++;
exist[u] = exist[v] = true;
marge(u,v);
}
int flag = 0;
for(int i = 0; i < 26; i++){
if(exist[i] && father[i] == i) flag++;
}
if(flag >= 2){
cout<<"The door cannot be opened."<<endl;
continue;
}
int inn = 0, outn = 0,mark = 0;
for(int i = 0; i < 26; i++){
if(in[i] != out[i] && exist[i]){
if(1 == in[i] - out[i]) inn++;//入度比出度大1
else if(1 == out[i] - in[i]) outn++;
else{
mark = 1;
break;
}
}
}
if(mark){
cout<<"The door cannot be opened."<<endl;
continue;
}
else{
if(!(inn + outn) || (inn== 1 && outn == 1)) cout<<"Ordering is possible."<<endl;
else cout<<"The door cannot be opened."<<endl;
}
}
return 0;
}
欧拉回路的求解
确实对于求解方式没有弄明白,先记录一下
先给出模板
int stack[maxn];///maxn是边的最大数量
bool vis[maxn];
int bj;
void dfs(int now)
{
for(int i=head[now];i!=-1;i=tu[i].next)
if(!vis[i])
{
vis[i]=1;
vis[i^1]=1;///这里是求欧拉回路,这一题用不着写这句,因为可以走双向,无向图
//在跑无向图的时候要加上这一句
dfs(tu[i].to);
stcak[bj++]=i;///等于i是记录边,等于tu[i].to是记录点
}
}
这里的异或操作其实算是一种规律在存储无向图的时候由于我们存储的路的编号和这条路反方向的编号是连续的,比如 0,1、2 , 3这样我们对其中一个数求异或,得到的就是另一个数字,所以我们 采取这种方法把无向图的边给标记上。
poj2230
这个因为每条路可以正反方向走两次,所以直接当作存在两点之间的路径有两条有向边,然后当作有向图进行处理就可以了
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<iomanip>
using namespace std;
typedef long long ll;
const int N=10005;
const int maxn=100010;
int head[N];
int tot , ip;
struct edgenode
{
int to;
int next;
} tu[N * N];
void init()
{
memset(head,-1,sizeof(head));
}
void add(int u,int v)
{
ip++, tu[ip].to = v, tu[ip].next = head[u], head[u] = ip;
}
int ans[maxn];
bool vis[maxn];
void dfs(int now)
{
for(int i = head[now]; i != -1; i = tu[i].next)
if(!vis[i])
{
vis[i] = 1;
//vis[i^1]=1;
dfs(tu[i].to);
ans[tot++] = tu[i].to;
}
}
int main()
{
int m,n;
scanf("%d%d",&n,&m);
init();
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
tot = 0;
dfs(1);
for(int i = 0; i < tot; i++)
cout<<ans[i]<<endl;
cout<<1<<endl;
return 0;
}