• 欧拉回路与欧拉路径


        若图G中存在这样一条路径,从某个顶点出发,使得它恰通过G中每条边一次(通过每一个顶点可以多次),则称该路径为欧拉路径。若该路径是一个圈(回到起点),则称为欧拉(Euler)回路

        欧拉回路与欧拉路径的充要条件

            1)无向图存在欧拉回路的充要条件:一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。

            2)有向图存在欧拉回路的充要条件:一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。
       判断无向图是否存在欧拉回路:(1)图联通(dfs或者并查集判图联通)(2)所有顶点的度数均是偶数
       判断有向图是否存在欧拉回路:(1)底图(忽略边方向后的无向图)联通(2)每个顶点的入度等于出度
     
       判断无向图是否存在欧拉路径:(1)图联通(dfs或者并查集判图联通)(2)仅有2个顶点(起点和终点)的度数为奇数,其他顶点的度数均是偶数。
       判断有向图是否存在欧拉路径:(1)底图(忽略边方向后的无向图)联通(2)只有两个点的入度不等于出度,并且其中一个点出度恰好比入度大1,另一个恰好入度比出度小1,每个顶点其它每个点的入度等于出度
    1.http://poj.org/problem?id=2230
    本题目构建图时,每一对顶点添加两条方向相反的边。题目已经说一定具有回路,所以采用dfs从顶点1开始对边进行不重复的遍历一次即可,当所有边遍历完后,回到考虑起始点。
    //---dfs求欧拉回路
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn = 10000 + 5;
    
    struct edge{
    	int v;
    	bool vis;
    	edge(int i = 0) :v(i){ vis = 0; }
    };
    vector<edge>G[maxn];
    
    void dfs(int u){
    	for (int i = 0; i < G[u].size(); i++){
    		edge &e = G[u][i];
    		if (!e.vis){
    			e.vis = true;
    			dfs(e.v);
    		}
    	}
    	printf("%d
    ", u);
    }
    
    int main(){
    	int u, v, m, n;
    	while (~scanf("%d%d", &n, &m)){
    		for (int i = 0; i <=n; i++)G[i].clear();
    
    		for (int i = 0; i < m; i++){
    			scanf("%d%d", &u, &v);
    			G[u].push_back(edge(v));
    			G[v].push_back(edge(u));
    		}
    		dfs(1);
    	}
    
    	return 0;
    }
    

      2.http://poj.org/problem?id=2337

     首先用并查集判断是否可以构成欧拉回路。然后确定可以构成欧拉回路后再用dfs搜索出最小字典序点的欧拉道路。如果事先没有判断是否可以构成欧拉回路直接爆DFS来搜索,将会耗去大量时间。
    //---dfs求欧拉回路
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<vector>
    using namespace std;
    const int maxn = 1000 + 5;
    const int maxsize = 26;
    struct Edge{
    	Edge(int a = 0, int b = 0) :v(a), id(b), vis(0){}
    	int v;
    	int id;//char str[maxsize];
    	bool vis;
    };
    
    char str[maxn][maxsize];
    int p[maxn];
    int deg[26];
    vector<Edge>G[maxsize];
    int n;
    bool ans;
    int used[26];
    int parent[26];
    
    int getparent(int i){
    	if (parent[i] == -1)return i;
    	return parent[i] = getparent(parent[i]);
    }
    bool cmp(Edge a, Edge b){
    	return strcmp(str[a.id], str[b.id])<0;
    }
    
    void dfs(int u, int curr){
    	if (curr == n){
    		ans = 1;
    		printf("%s", str[p[0]]);
    		for (int i = 1; i < n; i++)printf(".%s",str[p[i]]);
    		printf("
    ");
    		return;
    	}
    	if (ans)return;
    	for (int i = 0; i < G[u].size(); i++){
    		Edge&e = G[u][i];
    		if (!e.vis){
    			e.vis = 1;
    			p[curr] = e.id;
    			dfs(e.v, curr + 1);
    			e.vis = 0; //撤回标志
    		}
    	}
    }
    int main(){
    	int T, i, u, v;
    	scanf("%d", &T);
    	while (T--){
    		memset(deg, 0, sizeof(deg));
    		memset(used, 0, sizeof(used));
    		memset(parent, -1, sizeof(parent));
    
    		for (i = 0; i < 26; i++)G[i].clear();
    		scanf("%d", &n);
    		int cc = 26;//联通块;
    		for (i = 0; i < n; i++){
    			scanf("%s", str[i]);
    			u = str[i][0] - 'a';
    			v = str[i][strlen(str[i]) - 1] - 'a';
    			deg[u]++; deg[v]--;
    			used[u] = used[v] = 1;
    			G[u].push_back(Edge(v, i));
    			u = getparent(u); v = getparent(v);
    			if (u != v){
    				cc--;
    				parent[u] = v;
    			}
    		}
    		vector<int>d;
    		for (i = 0; i < 26; i++){
    			if (!used[i])cc--;
    			else if (deg[i])d.push_back(deg[i]);
    		}
    
    		ans = 0;
    		if (cc == 1 && (d.empty() || d.size() == 2 && (d[0] == -1 || d[0] == 1)))ans = 1;
    		if (ans == 0){
    			printf("***
    "); continue;
    		}
    		for (i = 0; i < 26; i++)
    			sort(G[i].begin(), G[i].end(), cmp);
    		if (d.size() == 2){
    			for (i = 0; i < n; i++){
    				if (deg[i] == 1)break;
    			}
    		}
    		else{
    			i = 0;
    			while (!used[i])i++;
    		}
    		ans = 0;
    		dfs(i, 0);
    
    	}
    	return 0;
    }
    

      

     
  • 相关阅读:
    20145316《信息安全系统设计基础》第七周学习总结
    20145316 许心远《信息安全系统设计基础》第六周学习总结
    20145316 《信息安全系统设计基础》第五周学习总结
    20145316 《信息安全系统设计基础》第二周学习总结
    面试之关系型数据库
    面试之网络基础
    Java 并发
    Scrapy 组件的具体用法
    Scrapy 框架入门
    Spring Security 介绍与Demo
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5836798.html
Copyright © 2020-2023  润新知